JSON文本必须至少包含两个八位字节


70

我收到此错误,并且找不到该问题的任何合理答案,因此我想写一个问题的摘要。

如果您在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!

很好,很好。如果您不知道什么是八位位组,请阅读此文章以获取摘要和解决方案: 什么是JSON八位位组,为什么需要两个八位位组?

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

因此,现在我知道了错误的原因,应该使用哪种模式来处理此错误?我有点讨厌猴子修补JSON库以允许nil值。任何建议将不胜感激。


2
可能是由于一个绝对的MINIMUM有效javascript字符串是"",这是两个八位字节(而绝对的最小最小对象是{})。无论是谁写的,编码器/解析器都不认为这null也是有效的javascript值。
Marc B

Answers:


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

但是实际上,库应该能够处理这种情况并返回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)

是的,尽管我需要在尝试解析的所有地方重复此操作。也许我应该提交补丁。
科里(Cory)

向您可以使用的JSON模块添加了一个小补丁。它不涉及任何疯狂的方法来混淆魔术或任何东西,并且易于重用。
亚历克斯·韦恩

@Alex您将在哪里部署迷你补丁程序以在整个应用程序中捕获它?
RSG

1
@AlexWayne为什么不使用json.is_a?(String)&& json.length> = 2的JSON.parse(json)
Demetrius Michael先生

最好json = json.to_s.strip在parse_nil中接受它之前做
Amol Pujari

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

JSON.parse(data.presence || '{}')

原谅我的无知(可怜的Windows家伙)。我是否需要将“ data.presence &&”和“ JSON.parse”行添加到我的Podfile中?试过了,但我遇到了一个错误(如您可能预期的那样)
Yossi

3

根据json.org

JSON建立在两种结构上:

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

  2. 值的有序列表。在大多数语言中,这是通过数组,向量,列表或序列来实现的。

因此,顶层至少需要两个八位位组(8位)为{}[]

IMO,最好的解决方案是确保to的参数JSON.parse是分层对象或分层数组。:-)


这不再是事实。2014年3月发布的RFC 7159更新了这些限制。所有以下都是有效的JSON: ,nullfalsetrue42,,"Some string"{}[]

我认为这很严格。
calasyr

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

9
这非常糟糕,因为它可以挽救所有内容,包括您可能想知道的所有其他类型的解析器错误。
Mike Campbell
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.