我的服务器成功解析了一些JSON代码(因为丢失了)。我保留了结构,只是添加/更改了一些数据条目。现在,当我尝试解析它时,我的代码返回了以下错误:
JSON::ParserError in Static#testing4
Showing /home/user/website/app/views/static/testing4.html.erb where line #44 raised:
399: unexpected token at ' {
"title": "TITLE1",
"capital": "Rome",
"length": 2.7,
"date": "2017-1-2",
"tags": [
"Culture"
]
}],
"2": [
{
"title": "TITLE2",
"capital": "Paris",
"age": 1.2,
"date": "2017-2-1",
"tags": [
"Culture"
]
}]
}
'
这是我的代码。 问题是开头的{"1":[
由于某种原因未被解析。此视图没有关联的控制器操作。
<!--testing4.html.erb-->
<%
require 'json'
require 'pp'
json = <<END_OF_JSON
{
"1": [
{
"title": "TITLE1",
"capital": "Rome",
"length": 2.7,
"date": "2017-1-2",
"tags": [
"Culture"
]
}],
"2": [
{
"title": "TITLE2",
"capital": "Paris",
"age": 1.2,
"date": "2017-2-1",
"tags": [
"Culture"
]
}]
}
END_OF_JSON
%>
<%= obj = JSON.parse(json) %>
尝试输出它而不解析它会产生以下结果:
<%
require 'json'
require 'pp'
json = <<END_OF_JSON
{
"1": [
{
"title": "TITLE1",
"capital": "Rome",
"length": 2.7,
"date": "2017-1-2",
"tags": [
"Culture"
]
}],
"2": [
{
"title": "TITLE2",
"capital": "Paris",
"age": 1.2,
"date": "2017-2-1",
"tags": [
"Culture"
]
}]
}
END_OF_JSON
%>
PUTS: <%= puts json %><br>
PP: <%= pp json %>
---output---
PUTS:
PP: { "1": [ { "title": "TITLE1", "capital": "Rome", "length": 2.7, "date": "2017-1-2", "tags": [ "Culture" ] }], "2": [ { "title": "TITLE2", "capital": "Paris", "age": 1.2, "date": "2017-2-1", "tags": [ "Culture" ] }] }
答案 0 :(得分:2)
jsonlint不可靠,还是还有其他事情发生?
jsonlint是可靠的,ruby在解析你发布的json方面没有问题:
require 'json'
require 'pp'
json = <<END_OF_JSON
{
"1": [
{
"title": "TITLE1",
"capital": "Rome",
"length": 2.7,
"date": "2017-1-2",
"tags": [
"Culture"
]
}],
"2": [
{
"title": "TITLE2",
"capital": "Paris",
"age": 1.2,
"date": "2017-2-1",
"tags": [
"Culture"
]
}]
}
END_OF_JSON
obj = JSON.parse(json)
pp obj
--output:--
{"1"=>
[{"title"=>"TITLE1",
"capital"=>"Rome",
"length"=>2.7,
"date"=>"2017-1-2",
"tags"=>["Culture"]}],
"2"=>
[{"title"=>"TITLE2",
"capital"=>"Paris",
"age"=>1.2,
"date"=>"2017-2-1",
"tags"=>["Culture"]}]}
但是,如果您查看文件或输出字符串,则非打印字符不一定是可见的:
test = "\001hello"
puts test
p test
--output:--
hello
"\u0001hello"
这里你会得到一个解析错误:
require 'json'
require 'pp'
json = <<END_OF_JSON
{
\001"1": [1, 2, 3]
}
END_OF_JSON
obj = JSON.parse(json)
即使输出时json看起来很好:
require 'json'
require 'pp'
json = <<END_OF_JSON
{
\001"1": [1, 2, 3]
}
END_OF_JSON
puts json
obj = JSON.parse(json)
--output:--
{
"1": [1, 2, 3]
}
/Users/7stud/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/json/common.rb:156:in `parse': 784: unexpected token at '{ (JSON::ParserError)
"1": [1, 2, 3]
}
'
from /Users/7stud/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/json/common.rb:156:in `parse'
from 1.rb:11:in `<main>'
因此,您可能希望从文件中读取json,然后使用p
输出文本,然后检查文本是否有任何奇怪的字符。
另外,请复制并粘贴完整的错误消息 - 不要输入您认为错误消息的内容,然后声明这是您的程序生成的内容。我可以复制你用这个json发布的错误信息:
json = <<END_OF_JSON
(code) = {
"1": [
{
"title": "TITLE1",
"capital": "Rome",
"length": 2.7,
"date": "2017-1-2",
"tags": [
"Culture"
]
}],
"2": [
{
"title": "TITLE2",
"capital": "Paris",
"age": 1.2,
"date": "2017-2-1",
"tags": [
"Culture"
]
}]
}
END_OF_JSON
obj = JSON.parse(json)
--output:--
`parse': 784: unexpected token at '(code) = { (JSON::ParserError)
"1": [
{
"title": "TITLE1",
"capital": "Rome",
"length": 2.7,
"date": "2017-1-2",
"tags": [
"Culture"
]
}],
"2": [
{
"title": "TITLE2",
"capital": "Paris",
"age": 1.2,
"date": "2017-2-1",
"tags": [
"Culture"
]
}]
}
'
from /Users/7stud/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/json/common.rb:156:in `parse'
from 1.rb:29:in `<main>'
对评论1的回复:
错误消息包含rails正在看到的json,这里是:
399: unexpected token at ' { #<===Opening brace, which starts a javascript object.
"title": "TITLE1",
"capital": "Rome",
"length": 2.7,
"date": "2017-1-2",
"tags": [
"Culture"
]
}], #<====First, a closing brace that ends the javascript object, followed by a closing bracket, ending what?
"2": [
{
"title": "TITLE2",
"capital": "Paris",
"age": 1.2,
"date": "2017-2-1",
"tags": [
"Culture"
]
}]
}
如果我将无效的json放在rails视图中:
<%
json = <<END_OF_JSON
{
"title": "TITLE1",
"capital": "Rome",
"length": 2.7,
"date": "2017-1-2",
"tags": [
"Culture"
]
}],
"2": [
{
"title": "TITLE2",
"capital": "Paris",
"age": 1.2,
"date": "2017-2-1",
"tags": [
"Culture"
]
}]
}
END_OF_JSON
obj = JSON.parse(json)
%>
...然后在我的浏览器中输入将显示该视图的路径,这是我在浏览器中收到的错误消息:
Showing /Users/7stud/rails_projects/test4/app/views/users/index.html.erb where line #27 raised:
784: unexpected token at '{
"title": "TITLE1",
"capital": "Rome",
"length": 2.7,
"date": "2017-1-2",
"tags": [
"Culture"
]
}],
"2": [
{
"title": "TITLE2",
"capital": "Paris",
"age": 1.2,
"date": "2017-2-1",
"tags": [
"Culture"
]
}]
}
'
看起来很熟悉?如果你在json的其他地方有错误,就像这里:
<%
json = <<END_OF_JSON
{
"1": [
{
"title": "TITLE1",
"capital": "Rome",
"length": 2.7,
"date": "2017-1-2",
"tags": [
"Culture"
]
}
],
"2": #<====Missing opening bracket
{
"title": "TITLE2",
"capital": "Paris",
"age": 1.2,
"date": "2017-2-1",
"tags": [
"Culture"
]
}
]
}
END_OF_JSON
obj = JSON.parse(json)
%>
然后您会在浏览器中看到如下错误消息:
Showing /Users/7stud/rails_projects/test4/app/views/users/index.html.erb where line #32 raised:
784: unexpected token at '{
"1": [ #<===Note the presence of "1": [, unlike in your error message.
{
"title": "TITLE1",
"capital": "Rome",
"length": 2.7,
"date": "2017-1-2",
"tags": [
"Culture"
]
}
],
"2":
{
"title": "TITLE2",
"capital": "Paris",
"age": 1.2,
"date": "2017-2-1",
"tags": [
"Culture"
]
}
]
}
'
因此,导轨看到的json中不存在"1": [
。如果您需要更多帮助,则需要复制并粘贴以下代码:
对评论2的回复:
rails视图能够呈现以下json而不会出现错误(删除所有空格):
<!--testing4.html.erb-->
<%
require 'json'
require 'pp'
json = <<END_OF_JSON
{
"1": [{"title": "TITLE1", "capital": "Rome", "length": 2.7, "date": "2017-1-2", "tags": ["Culture"]}],
"2": [{"title": "TITLE2", "capital": "Paris", "age": 1.2, "date": "2017-2-1", "tags": ["Culture"]}]
}
END_OF_JSON
%>
<%= obj = JSON.parse(json) %>
并且,rails视图能够呈现以下json而不会出现错误(所有空格都重新添加):
<!--testing4.html.erb-->
<%
require 'json'
require 'pp'
json = <<END_OF_JSON
{
"1": [
{
"title": "TITLE1",
"capital": "Rome",
"length": 2.7,
"date": "2017-1-2",
"tags": [
"Culture"
]
}],
"2": [
{
"title": "TITLE2",
"capital": "Paris",
"age": 1.2, "date":
"2017-2-1",
"tags": [
"Culture"
]
}]
}
END_OF_JSON
%>
<%= obj = JSON.parse(json) %>
但是,由于某种原因,rails视图无法呈现您的json:
<!--testing4.html.erb-->
<%
require 'json'
require 'pp'
json = <<END_OF_JSON
{
"1": [
{
"title": "TITLE1",
"capital": "Rome",
"length": 2.7,
"date": "2017-1-2",
"tags": [
"Culture"
]
}],
"2": [
{
"title": "TITLE2",
"capital": "Paris",
"age": 1.2,
"date": "2017-2-1",
"tags": [
"Culture"
]
}]
}
END_OF_JSON
%>
<%= obj = JSON.parse(json) %>
经过一些进一步调查后,你的json混合了ascii空格(十六进制表示法为20)和一种称为EM SPACE
U+2003
e2 80 83
EM SPACE
的UTF-8空格字符在UTF-8)。你的json中的第一个{
"1": [
{
^
|
Right there
出现在这里:
7b
...巧合的是,rails错误信息正在切断你的json。紧接在该开头括号(十六进制表示法中的20
)之前是ascii空格(十六进制表示法中的EM SPACE
),ascii空格前面的字符是一个三字节UTF-8字符,称为{{1 (U + 2003,UTF-8中的e2 80 83
)。以UTF-8编码编码的字符应该是合法的json。 jsonlint接受EM SPACE
,但是在它上面有阻塞。
作为问题的一个简短示例,以下javascript数组在每个逗号后面都有EM SPACE
:
<!--testing4.html.erb-->
<%
json = "[1, 2, 3]"
%>
<%= obj = JSON.parse(json) %>
以下是我浏览器中的错误:
419: unexpected token at ' 2, 3]'
导轨错误会将json切断到第一个EM SPACE
。
事实证明,虽然json中允许使用UTF-8字符,但json术语之间只允许使用几个ascii空格字符 - 而不仅仅是任何UTF-8字符。见RFC 7159。在json术语之间使用EM SPACE
在概念上等同于在术语之间使用z
。因此,包含EM SPACE
个字符的json是非法的json。在字符串中使用EM SPACE
是合法的,但不能在json术语之间使用。
以下jsonlinter报告带有EM SPACE字符的json无效:
http://www.freeformatter.com/json-validator.html
似乎有些jsonlinters比其他人更可靠。
解决方案:
您可以使用gsub()
将所有EM SPACE
字符替换为ascii空格:
...
...
END_OF_JSON
clean_json = json.gsub("\u2003", ' ')
%>
<%= obj = JSON.parse(clean_json) %>
如果你从某个地方的服务中得到了json,你应该给他们发一封电子邮件,让他们知道他们发出的json是非法的。