在我的控制器,下面的作品(版画 “奥凯”)JSON编码错误地逃脱(Rails 3中,红宝石1.9.2)
puts obj.inspect
但这并不(呈现 “OK \ u00e9”)
render :json => obj
显然to_json
方法转义unicode字符。有没有选择来防止这种情况发生?
在我的控制器,下面的作品(版画 “奥凯”)JSON编码错误地逃脱(Rails 3中,红宝石1.9.2)
puts obj.inspect
但这并不(呈现 “OK \ u00e9”)
render :json => obj
显然to_json
方法转义unicode字符。有没有选择来防止这种情况发生?
如果你挖通了源,你会最终得出ActiveSupport::JSON::Encoding
和escape
方法:
def escape(string)
if string.respond_to?(:force_encoding)
string = string.encode(::Encoding::UTF_8, :undef => :replace).force_encoding(::Encoding::BINARY)
end
json = string.
gsub(escape_regex) { |s| ESCAPED_CHARS[s] }.
gsub(/([\xC0-\xDF][\x80-\xBF]|
[\xE0-\xEF][\x80-\xBF]{2}|
[\xF0-\xF7][\x80-\xBF]{3})+/nx) { |s|
s.unpack("U*").pack("n*").unpack("H*")[0].gsub(/.{4}/n, '\\\\u\&')
}
json = %("#{json}")
json.force_encoding(::Encoding::UTF_8) if json.respond_to?(:force_encoding)
json
end
各种gsub
呼叫迫使非ASCII UTF-8的\uXXXX
符号,你看到的。任何处理JSON的东西都应该可以接受十六进制编码的UTF-8,但是如果需要,您可以总是后处理JSON(或修改后的JSON助手中的猴子补丁)以将\uXXXX
表示法转换为原始UTF-8。
我同意强迫JSON是7位清理是有点虚假,但你去。
简答:没有。
这是正确的编码。 JSON不需要请求需要转义的Unicode字符,但JSON库生成仅包含7位ASCII字符的输出是很常见的,以避免在传输过程中出现任何潜在的编码问题。
任何JSON解释程序都将能够使用该字符串并重现原件。要查看这个动作,只需在浏览器的地址栏中输入javascript:alert("ok\u00e9")
即可。
这个人是正确的:thumbsup: – freedrull 2012-09-13 19:40:30
要设置为\ uXXXX码回UTF-8:
json_string.gsub!(/\\u([0-9a-z]{4})/) {|s| [$1.to_i(16)].pack("U")}
解决了我的json编码问题,非常感谢 – Fizz 2013-11-11 15:41:22
可以防止由猴子修补通过姆姆提到的方法是太短了。将以下内容放入config/initializers/patches.rb(或用于修补内容的类似文件),并重新启动您的Rails进程以使更改生效。
module ActiveSupport::JSON::Encoding
class << self
def escape(string)
if string.respond_to?(:force_encoding)
string = string.encode(::Encoding::UTF_8, :undef => :replace).force_encoding(::Encoding::BINARY)
end
json = string.gsub(escape_regex) { |s| ESCAPED_CHARS[s] }
json = %("#{json}")
json.force_encoding(::Encoding::UTF_8) if json.respond_to?(:force_encoding)
json
end
end
end
请注意,无法保证该修补程序可与未来版本的ActiveSupport一起使用。编写这篇文章时使用的版本是3.1.3。
尽我所能做到这一点,它完全解决了JSON问题中的表情符号。谢谢! – 2012-06-09 16:39:13
Rails 3.1.6仍然存在问题,并且此修补程序仍然修复它。 Rails团队确实需要用他们的JSON编码来解决这个问题;表情符号不会消失,尤其是现在它已成为Unicode标准的一部分。 – poetmountain 2012-07-22 00:35:41
看到这个不太可怕的解决方案:http://stackoverflow.com/questions/683989/how-do-you-deal-with-the-conflict-between-activesupportjson-and-the-json-gem/3285570#3285570 – vish 2012-12-17 17:59:40
我有一个非常棘手的方法来解决这个问题。好吧,如果to_json
没让你有正确的代码,那么你可以直接尝试写:
render text: tags
render json: tags
或render json: tags.to_json
总会自动传输的编码风格,但如果你使用render text:tags
,那么该字符串将保持原样。我认为jQuery仍然可以识别数据。
字符没有逃脱与Rails2.3.11/Ruby1.8
其他方法为Unicode所以我用了以下内容:
render :json => JSON::dump(obj)
是的,这工作在1.8和轨道2.3。好的。 – user589473 2013-07-09 23:43:51
渲染:JSON将调用.to_json的对象,如果它不是一个字符串。你可以这样做避免这个问题:
render :json => JSON.generate(obj)
这将字符串直接传递,因此避免调用的ActiveSupport的to_json。
另一种方法是重写to_json你序列化对象,所以在这种情况下,你可以这样做:
class Foo < ActiveRecord::Base
def to_json(options = {})
JSON.generate(as_json)
end
end
如果您使用ActiveModelSerializers,你可以通过重写to_json解决这个问题在您的序列化程序中:
# controller
respond_with foo, :serializer => MySerializer
# serializer
attributes :bar, :baz
def to_json(options = {})
JSON.generate(serializable_hash)
end
这不是数据库问题。 – 2011-02-26 00:08:53