JSON 编码错误转义(Rails 3、Ruby 1.9.2)
在我的控制器中,以下内容有效(打印“oké”)
puts obj.inspect
但这不起作用(呈现“ok\u00e9”)
render :json => obj
显然 to_json
方法转义了 unicode 字符。有没有办法可以防止这种情况发生?
In my controller, the following works (prints "oké")
puts obj.inspect
But this doesn't (renders "ok\u00e9")
render :json => obj
Apparently the to_json
method escapes unicode characters. Is there an option to prevent this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
要将 \uXXXX 代码设置回 utf-8:
To set the \uXXXX codes back to utf-8:
你可以通过猴子补丁来防止它,mu提到的方法太短了。将以下内容放入 config/initializers/patches.rb (或用于修补内容的类似文件)中,然后重新启动 Rails 进程以使更改生效。
请注意,无法保证该补丁适用于 ActiveSupport 的未来版本。写这篇文章时使用的版本是3.1.3。
You can prevent it by monkey-patching the method mentioned by mu is too short. Put the following into config/initializers/patches.rb (or similar file used for patching stuff) and restart your rails process for the change to take effect.
Be advised that there's no guarantee that the patch will work with future versions of ActiveSupport. The version used when writing this post is 3.1.3.
如果您深入研究源代码,您最终会看到
ActiveSupport: :JSON::Encoding
和escape
方法:各种
gsub
调用将非 ASCII UTF-8 强制转换为您所看到的\uXXXX
表示法。十六进制编码的 UTF-8 应该可以接受任何处理 JSON 的内容,但您始终可以对 JSON(或修改后的 JSON 转义器中的猴子补丁)进行后处理,以将\uXXXX
表示法转换为原始 UTF-8如果需要的话。我同意强制 JSON 为 7 位干净有点假,但你就知道了。
简短的回答:不。
If you dig through the source you'll eventually come to
ActiveSupport::JSON::Encoding
and theescape
method:The various
gsub
calls are forcing non-ASCII UTF-8 to the\uXXXX
notation that you're seeing. Hex encoded UTF-8 should be acceptable to anything that processes JSON but you could always post-process the JSON (or monkey patch in a modified JSON escaper) to convert the\uXXXX
notation to raw UTF-8 if necessary.I'd agree that forcing JSON to be 7bit-clean is a bit bogus but there you go.
Short answer: no.
使用
Rails2.3.11/Ruby1.8
中的其他方法不会将字符转义为 unicode,因此我使用了以下方法:Characters were not escaped to unicode with the other methods in
Rails2.3.11/Ruby1.8
so I used the following:这是正确的编码。 JSON 不要求转义 Unicode 字符,但 JSON 库通常会生成仅包含 7 位 ASCII 字符的输出,以避免传输过程中出现任何潜在的编码问题。
任何 JSON 解释器都能够使用该字符串并重现原始字符串。要查看实际效果,只需在浏览器的地址栏中输入
javascript:alert("ok\u00e9")
即可。That is the correct encoding. JSON doesn't requre Unicode characters to be escaped, but it is common for JSON libraries to produce output which contains only 7-bit ASCII characters, to avoid any potential encoding problems in transit.
Any JSON interpreter will be able to consume that string and reproduce the original. To see this in action, just type
javascript:alert("ok\u00e9")
into your browser's location bar.如果对象不是字符串,则 render :json 将调用 .to_json 。您可以通过执行以下操作来避免此问题:
这将直接传递字符串,从而避免调用 ActiveSupport 的 to_json。
另一种方法是在要序列化的对象上覆盖 to_json ,因此在这种情况下,您可以执行以下操作:
如果您使用 ActiveModelSerializers,则可以通过在序列化程序中覆盖 to_json 来解决此问题:
render :json will call .to_json on the object if it's not a string. You can avoid this problem by doing:
This will by pass a string directly and therefore avoid the call to ActiveSupport's to_json.
Another approach would be to override to_json on the object you are serializing, so in that case, you could do something like:
And if you use ActiveModelSerializers, you can solve this problem by overriding to_json in your serializer:
我有一个非常棘手的方法来解决这个问题。好吧,如果
to_json
不允许您拥有正确的代码,那么您可以直接尝试编写:render json:tags
或render json:tags.to_json
将始终自动传输编码样式,但如果您使用render text:tags
,则字符串将保持原样。我认为 jQuery 仍然可以识别数据。I have got a very tricky way to solve this problem. Well, if
to_json
did not allow you to have the correct code, then you could directly try to write :render json: tags
orrender json: tags.to_json
will always auto transfer the encoding style, but if you userender text:tags
, then the string will stay as it is. And I think jQuery could still recognize the data.