我遇到的问题是,当JavaScripts JSON.parse
解析时,Ruby脚本生成的JSON不兼容。请考虑以下示例:
# Ruby
require 'json'
hash = {}
hash["key"] = "value with \u001a unicode"
hash.to_json
=> '{"key":"value with \u001a unicode"}'
// JavaScript
JSON.parse('{"key":"value with \u001a unicode"}')
=> JSON.parse: bad control character in string literal at line 1 column 2 of the JSON data
问题是unicode字符\u001a
。解决这个问题的方法是将\u001a
转义为\\u001a
,但事实是,\u001a
会被Ruby自动插入到字符串中。我无法可靠地对结果进行后期处理。关于如何解决这个问题的任何想法?
请注意,我希望在JavaScript执行环境中调用JSON.parse
,而不是在Ruby的解释器中。
答案 0 :(得分:2)
简短版本是您在尝试将其解码为JSON之前将字符串解释为Javascript表达式。
U + 001A是一个控制角色。 RFC 4627 explicitly disallows control characters U+0000-U+001F in quoted strings。这里的问题不是JSON无效,而是在尝试将它们解析为JSON之前,你是在取消控制字符。
当您从Ruby转储字符串"\u001a"
并将其复制并粘贴到Javascript解释器中时,转义序列将转换为未转义的控制字符,该字符不是JSON中的有效字符!非禁止字符可以正常工作 - 例如,您可以愉快JSON.parse('["\u0020"]')
。
但是,如果不将字符串解释为Javascript,而是将其作为原始字节读取,则会正确解析。
$ irb
irb(main):001:0> require 'json'
=> true
irb(main):003:0> open("out.json", "w") {|f| f.print JSON.dump(["\u001a"]) }
=> nil
$ node -e 'require("fs").readFile("out.json", function(err, data) { console.log(JSON.parse(data)); });'
[ '\u001a' ]
如果您要复制粘贴,则需要复制字符串的转义版本,这样当您的Javascript引擎解析字符串时,转义符双重转义序列正确地转换为逃避序列而不是字符。因此,您应该复制JSON.dump(["\u001a"])
的输出,而不是复制puts JSON.dump(["\u001a"]).inspect
的输出,这将正确地转义字符串中的任何转义序列。
答案 1 :(得分:0)
对我来说,遵循ruby代码会给"{\"key\":\"value with \\u001a unicode\"}"
在输出中。
JSON.parse
也可以通过它。并给出Object {key: "value with unicode"}
。
答案 2 :(得分:0)
According to the RFC:
JSON text is encoded in unicode. The default unicode is utf-8.
I ran your code in irb and got the following:
1.9.3-p484 :001 > require 'json'
=> true
1.9.3-p484 :002 >
1.9.3-p484 :003 > hash = {}
=> {}
1.9.3-p484 :004 > hash["key"] = "value with \u001a unicode"
=> "value with \u001A unicode"
1.9.3-p484 :005 > hash.to_json
=> "{\"key\":\"value with \\u001a unicode\"}"
Then running the returned string in a javascript console, I get the following:
> JSON.parse("{\"key\":\"value with \\u001a unicode\"}")
> Object {key: "value with unicode"}
It is returning an object. To get the value with unicode, you have to access the hash by calling:
> str = JSON.parse("{\"key\":\"value with \\u001a unicode\"}")
> Object {key: "value with unicode"}
> str.key
> "value with unicode"