2011-12-05 145 views
56

我收到此错误,并且找不到任何合理的答案来解决这个问题,所以我想我会写一个问题摘要。JSON文本必须至少包含两个八位字节

如果运行这个片段在IRB:

JSON.parse(nil) 

你会看到以下错误:

TypeError: can't convert nil into String 

我是种期待函数返回nil,而不是一个TypeError。如果您使用转换所有to_s输入,然后你会看到八位字节错误:

JSON::ParserError: A JSON text must at least contain two octets! 

这只是罚款和好。如果你不知道一个字节是什么,看到这篇文章的总结和解决方案: What is a JSON octet and why are two required?

解决方案

你传递中的变量是一个空字符串。不要试图在JSON.parse方法中使用空字符串。

问题

所以,现在我知道了错误的原因,我应该用什么方式来处理呢?我有点厌恶猴子修补JSON库允许nil值。任何建议将不胜感激。

+2

可能是由于绝对最小有效javascript字符串是''“',这是两个八位字节(而绝对最小对象是'{}'')。可能是编写该编码器/解析器的人不认为'null'也是一个有效的javascript值。 –

回答

41
parsed = json && json.length >= 2 ? JSON.parse(json) : nil 

但实际上库应该能够处理这种情况并返回零。内置JSON支持的Web浏览器似乎能像您期望的那样工作。


或者用只有轻微侵入性微型贴片做到这一点:

module JSON 
    def self.parse_nil(json) 
    JSON.parse(json) if json && json.length >= 2 
    end 
end 

parsed = JSON.parse_nil(json) 
+0

是的,虽然我需要在任何地方重复这一点,我试图解析。也许我应该提交一个补丁。 – Cory

+0

为您可以改为使用的JSON模块添加一个小的补丁。它不涉及任何疯狂的方法别名魔术或任何东西,并且很容易重用。 –

+0

@Alex您会在哪里部署迷你补丁以在整个应用程序中捕获此内容? – RSG

0
hash = JSON.parse(json) rescue {} 
array = JSON.parse(json) rescue [] 
string = JSON.parse(json) rescue '' 
+9

这是非常糟糕的它会拯救任何东西,包括你可能想知道的所有其他类型的解析器错误。 –

+0

这是真的。你应该知道这一点,并决定在什么情况下这是有用的...... – Ich

3

根据json.org

JSON是建立在两个结构:

  1. 名称/值的集合e对。在各种语言中,这被实现为对象,记录,结构,字典,散列表,键控列表或关联数组。

  2. 值的有序列表。在大多数语言中,这是作为数组,矢量,列表或序列实现的。

所以,在顶层将是所需的最小两个八位组(8位){}[]

IMO,最好的解决方案将是,以确保参数JSON.parse或者是一个strigified对象或一个严格的数组。:-)

+0

这不再是真实的。 2014年3月的[RFC 7159](https://tools.ietf.org/html/rfc7159)更新了这些限制。所有以下内容都是有效的JSON:'null','false','true','42',''一些字符串'​​','{}','[]' – Dan

1
data.presence && JSON.parse(data) 

JSON.parse(data.presence || '{}') 
相关问题