为什么to_json在Rails 4中自动转义unicode?

Rails 3:

{"a" => "
"}.to_json => "{\"a\":\"
\"}"

导轨4:

 {"a" => "
"}.to_json => "{\"a\":\"\\u003Cbr/\\u003E\"}"

为什么???

它似乎导致错误

 Encoding::UndefinedConversionError: "\xC3" from ASCII-8BIT to UTF-8 

当我的Rails 3应用程序尝试解析我的rails 4应用程序生成的JSON时。

为什么???

防范Web应用程序中的常见弱点。 如果你在HTML页面中说,例如:

  

然后你可能会认为你很好,因为你已经JSON转义了你注入JavaScript的数据。 但实际上你并不安全:除了JSON语法之外,你还有周围的HTML语法,而在HTML脚本块中是带内信令。 实际上,如果@something包含字符串则会出现一个跨站点脚本漏洞:

  

第一个脚本块在字符串的中间结束(留下未封闭的字符串文字语法错误),第二个被视为新的脚本块,并且其中的潜在用户提交的内容被执行。

JSON不需要将<字符转义为\u003C ,但它是一个完全有效的替代方案,它会自动避免这类问题。 如果JSON解析器拒绝它,那么这是读者中的一个严重错误。

产生该错误的代码是什么? 我不相信错误与< -escaping有关,因为它讨论的是字节0xC3而不是0x3C。 这可能表示UTF-8编码内容的字符串未被标记为UTF-8 ...也许您需要在输入上使用force_encoding("UTF-8")

您可以使用JSON::dump保留原始字符串:

 JSON::dump "a" => "
" => "{\"a\":\"
\"}" JSON::dump "a" => "x&y" => {\"a\":\"x&y\"}" # instead of x\u0026y

小心使用它,因为bobince提到的原因,特别是用任何用户生成的输入(或至少确保已经消毒)来避免它。

这是我遇到的一个合法用途的例子。 在辅助函数中生成JavaScript哈希参数:

 # application_helper.rb def widget_js(post) options = { color: ColorCalculator(post.color).to_rgb_hex, ... } "third_party_widget(#{JSON::dump options});" end