Haml中如何执行传入变量中的Ruby代码?
Haml中变量传入的Ruby代码无法执行的原因及解决方案
问题现象
在Haml模板里直接写Ruby代码(比如7*7),能正常执行并输出计算结果49;但如果把Ruby代码以字符串形式通过变量(比如请求参数7*7赋值给@user_input)传入模板,不管是用#{@user_input}插值还是直接= @user_input输出,变量内容只会显示原始字符串7*7,不会被执行计算。你的示例代码和输出也验证了这一点。
原因分析
Haml的Ruby插值、表达式输出功能,只会解析模板编译阶段就存在的Ruby代码。变量里的字符串内容会被Haml当作普通文本处理,不会被当作Ruby代码执行——这是安全设计,防止恶意用户通过传入可执行代码进行注入攻击,避免服务器执行危险操作。
解决方案(注意安全风险)
如果你的场景确实需要执行变量中的Ruby代码(必须确保输入来源完全可信,比如仅内部测试、无外部用户输入),可以用Ruby的eval方法执行字符串形式的代码:
方法1:在控制器中预处理
修改Sinatra路由代码,提前执行变量内容:
require 'sinatra' require 'haml' get '/' do # 仅信任输入时使用!添加rescue避免执行出错导致服务崩溃 @user_input = eval(params[:foo_user_input]) rescue params[:foo_user_input] haml :foo end __END__ @@ foo %p= "hello" <br> %p= 7*7 <br> %p= #{@user_input} <br> %p This is #{7*7} cake! <br> %p This is #{@user_input} cake! <br> %p= @user_input <br>
方法2:在Haml模板中直接处理
在模板里对变量调用eval:
%p= "hello" <br> %p= 7*7 <br> %p= eval(@user_input) rescue @user_input <br> %p This is #{7*7} cake! <br> %p This is #{eval(@user_input) rescue @user_input} cake! <br> %p= eval(@user_input) rescue @user_input <br>
⚠️ 重要提醒:eval会执行任何传入的Ruby代码,若存在不可信外部输入,恶意代码可能删除文件、篡改数据甚至控制服务器,因此非必要绝对不要用eval处理用户输入。
内容的提问来源于stack exchange,提问作者fooBar
相关产品推荐
相关产品推荐

