为什么escape_javascript在渲染部分之前?
我正在看这个Railscast插曲 ,想知道为什么在这里需要调用escape_javascript
:
$("#reviews").append("<%= escape_javascript(render(:partial => @review)) %>");
什么是escape_javascript
用于?
根据Rails文档 :
escape_javascript(JavaScript的)
Escape运营商返回和JavaScript段的单引号和双引号。
但这对我来说没有多大意义。
因为你不希望用户发布浏览器实际执行的JavaScript?
如果将代码分为两部分,则更容易理解。
第一部分$("#reviews").append("<%= ... %>");
是JavaScript与erb。 这意味着<%= ... %>
将被其内部的ruby代码返回。 该replace的结果必须是有效的JavaScript,否则当客户端尝试处理时会引发错误。 所以这是第一件事:你需要有效的JavaScript 。
另一件要考虑的事情是,无论使用何种ruby生成,都必须包含在带有双引号的JavaScriptstring中 – 注意<%= ... %>
周围的双引号。 这意味着生成的JavaScript将如下所示:
$("#reviews").append("...");
现在让我们来看看<%= ... %>
里面的ruby部分。 什么render(:partial => @review)
呢? 它是呈现一个部分 – 这意味着它可以呈现任何types的代码 – HTML,CSS …甚至更多的JavaScript!
那么,如果我们的部分包含一些简单的HTML,像这样呢?
<a href="/mycontroller/myaction">Action!</a>
请记住,您的JavaScript是一个双引号的string作为参数? 如果我们简单地用该部分的代码replace<%= ... %>
,那么我们有一个问题 – 在href=
之后立即有一个双引号! 该javascript将无效:
// Without escaping, you get a broken javascript string at href $("#reviews").append("<a href="/mycontroller/myaction">Action!</a>");
为了避免这种情况的发生,你想逃避这些特殊字符,所以你的string不会被剪切 – 你需要的东西,而不是产生这个:
<a href=\"/mycontroller/myaction\">Action!</a>
这是escape_javascript
所做的。 它确保返回的string不会“打破”JavaScript。 如果你使用它,你会得到所需的输出:
$("#reviews").append("<a href=\"/mycontroller/myaction\">Action!</a>")
问候!
用户可能会发布恶意代码(恶意用户),如果未转义,可能会被执行,从而允许用户控制您的应用程序。
尝试这个:
<% variable = '"); alert("hi there' %> $("#reviews").append("<%= variable %>");
不是很熟悉rails的语法,但是如果你不转义variable
那么会显示一个警告框,我不认为这是行为。
如果你看这里的来源,它会更清晰。
这个function完成以下两件事:
-
它将inputstring中的字符replace为JS_ESCAPE_MAP中定义的字符
这样做的目的是为了确保JavaScript代码正确序列化,而不会干扰它所embedded的外部string。 例如,如果在双引号中有一个javascriptstring,则string文字中的所有引号都必须用单引号引起,以避免代码中断。
- 该函数还检查结果string是否安全。 如果不是,那么它会进行必要的转义,以确保string变为html安全并返回结果。
当你使用escape_javascript时,它通常被dynamic地embedded到另一个string或现有的html中。 你需要确保这样做不会使整个页面不呈现。
其他回复指出了这个回应的一些方面,但我想把所有的项目一起包括在JavaScript转义和html转义之间的区别。 此外,一些回应暗示此function有助于避免脚本注入。 我不认为这是这个function的目的。 例如,在您的评论中,如果您的评论有警报(“您在那里”),只需将其附加到节点不会触发popup窗口。 您没有将其embedded在页面加载或通过其他事件触发的函数中。 只是警告('你好')作为你的HTML的一部分,并不意味着它会执行为JavaScript。
这就是说我不否认脚本注入是不可能的。 但为了避免这一点,您需要采取措施,当你把用户数据存储在你的数据库。 您提供的function和示例与呈现已保存的信息有关。
我希望这有助于解决你的问题。
它不会执行你正在渲染的JavaScript