我正在看这个Railscast插曲,想知道为什么escape_javascript
需要在这里致电:
$("#reviews").append("<%= escape_javascript(render(:partial => @review)) %>");
有什么escape_javascript
用?
根据Rails的文档:
escape_javascript(javascript)
转义符返回以及JavaScript段的单引号和双引号。
但这对我来说意义不大。
我正在看这个Railscast插曲,想知道为什么escape_javascript
需要在这里致电:
$("#reviews").append("<%= escape_javascript(render(:partial => @review)) %>");
有什么escape_javascript
用?
根据Rails的文档:
escape_javascript(javascript)
转义符返回以及JavaScript段的单引号和双引号。
但这对我来说意义不大。
Answers:
如果将代码分为两部分,则更容易理解。
第一部分$("#reviews").append("<%= ... %>");
是带有erb的javascript。这意味着,<%= ... %>
它将被内部返回的任何红宝石代码替换。替换的结果必须是有效的javascript,否则客户端尝试对其进行处理时将抛出错误。这就是第一件事:您需要有效的javascript。
要考虑的另一件事是,ruby生成的任何内容都必须包含在带有双引号的javascript字符串内-注意周围的双引号<%= ... %>
。这意味着生成的javascript将如下所示:
$("#reviews").append("...");
现在,让我们检查中的红宝石部分<%= ... %>
。怎么render(:partial => @review)
办?它正在呈现部分代码-这意味着它可以呈现任何类型的代码-html,css ...甚至更多的javascript!
那么,如果我们的partial包含一些简单的html(如此)会发生什么呢?
<a href="/mycontroller/myaction">Action!</a>
还记得您的JavaScript将双引号字符串作为参数吗?如果我们简单地用<%= ... %>
那个部分的代码替换,那么我们就有问题了-紧跟在href=
双引号之后!JavaScript将无效:
// Without escaping, you get a broken javascript string at href
$("#reviews").append("<a href="/mycontroller/myaction">Action!</a>");
为了避免这种情况的发生,您希望转义这些特殊字符,以便不对字符串进行剪切-您需要生成此字符的东西:
<a href=\"/mycontroller/myaction\">Action!</a>
这是escape_javascript
做什么的。它确保返回的字符串不会“破坏” javascript。如果使用它,将获得所需的输出:
$("#reviews").append("<a href=\"/mycontroller/myaction\">Action!</a>")
问候!
escape_for_javascript
,因为通常您会转义其他代码(例如html),以免破坏javascript。
escape_javascript()
现在有一个更短的方法:简单j()
(至少在Rails 4中)。
如果您在此处查看源代码,它将更加清晰。
此功能完成以下两件事:
它将输入字符串中的字符替换为JS_ESCAPE_MAP中定义的字符
这样做的目的是确保javascript代码正确序列化,而不会干扰嵌入它的外部字符串。例如,如果您的JavaScript字符串用双引号引起来,则字符串文字中的所有引号都必须用单引号引起来,以免破坏代码。
当您使用escape_javascript时,通常会动态地将其嵌入到另一个字符串或现有的html中。您需要确保这样做不会使整个页面无法呈现。
其他回应中指出了此回应的某些方面,但我希望将所有内容放在一起,包括javascript逸出和html逸出之间的区别。另外,一些响应暗示此功能有助于避免脚本注入。我认为这不是此功能的目的。例如,在您的评论中,如果您的评论具有警报(“嗨,那里”),则仅将其附加到节点将不会触发弹出窗口。您没有将其嵌入在页面加载或通过其他事件触发的函数中。仅将alert('hi there')作为您的html的一部分并不意味着它将作为javascript执行。
话虽如此,但我并不否认不可能进行脚本注入。但是要避免这种情况,在获取用户数据并将其存储在数据库中时需要采取步骤。您提供的功能和示例与呈现已保存的信息有关。
希望这对您有所帮助。