如果您使用JSON解码包含一个值的内容,该值包含一个反斜杠的“n”来表示换行符,那么您应该在什么时候将其替换为一个真正的换行符?
这里有一个人为的例子:
let dict = ["key": "value\\nvalue"]
let json = try! JSONEncoder().encode(dict)
let result = try! JSONDecoder().decode([String:String].self, from: json)
print(result["key"])
字符串
这将输出"value\\nvalue"
,但为了在我的应用程序中显示,我随后调用replacingOccurrences
将"\\n"
(表示反斜线n”)更改为"\n"
(表示换行符),以便在我的界面中显示实际的换行符。
现在,我有点惊讶JSONDecoder还没有为我做这件事。正如它有一个可配置的策略将日期字符串值解码为日期一样,我希望它至少有一个可配置的策略将字符串值解码为字符串。但事实并非如此
我的问题是:一般情况下,人们会怎么处理这种情况?像我在我的应用程序中所做的那样,逐个处理它感觉不对;实际上,这些JSON数据来自服务器,我希望 * 所有 * JSON HTTP响应体都以这种方式处理。
2条答案
按热度按时间jchrr9hc1#
看起来服务器正在发送5c 5c 6 e(即反斜杠-反斜杠-n或
\\n
)。这是有效的JSON,但它并不意味着“换行符”。它意味着“反斜杠-n”(\
后跟n
)。如果服务器想要发送换行符,那就是编码错误。它需要是5c 6 e,“反斜杠-n”。当然,你可以在客户端修复它,但是没有“正常”的方法来做到这一点,因为它是错误的。解决这个问题的正确方法是在服务器端解决它。您可以在客户端对字符串进行双重取消转义,但这是不明确的,除非没有更好的方法,否则我不建议使用它。当字符串中出现实际的反斜杠时,重复地取消转义往往会把事情搞砸。
JSON字符串中不允许“文字换行符”,因为引号之间不允许字节0a。将其放入JSONLint应该会失败。但是5c 6 e(反斜杠-n或
\n
)是,并且是正确的方法。3duebb1j2#
后端未正确提供数据。
JSONEncoder
和JSONDecoder
可以正确地转义和取消转义字符。我需要的是...武装告诉我的老板告诉服务器的人不要这样做。
您可以告诉您的老板,原始JSON有效负载应该是
5c6e
,而不是5c5c6e
。如果您接收的JSON中包含5c5c6e
,则服务器提供的换行符(0a
)被错误地转义了两次。除此之外,我们不能再具体了。话虽如此,这个问题可能有两个来源之一:
1.实际的服务器数据库/模型包含
5c6e
而不是0a
,JSON编码(正如它应该的那样)将初始5c
转换为5c5c
,从而导致最终原始JSON有效载荷中的5c5c6e
;或者是1.数据库/模型包含
0a
,后端开发人员不知道标准JSON编码例程将正确地转义/转换为5c6e
,并且手动(无论是否有意)将其自身转换为5c6e
,并且服务器的JSON编码器再次(正确)将其转换为5c5c6e
。第一种情况可能是发生了什么,但我们没有足够的信息来进一步诊断。您可能需要一些后端开发人员查看数据库中实际内容的十六进制表示,以找出问题所在。
值得一提的是,如果第一个场景适用,那么可能需要在这个过程中更进一步地追溯到
5c6e
最初是如何进入数据库/模型的(如果确实如此)。我们应该认识到,这可能根本不是服务器的bug,而是一个垃圾进垃圾出的问题。即,一些客户端应用程序可能已经过度转义了原始输入。也许客户端应用程序输入了
0a
换行符,添加了转义符,并将5c6e
提供给其JSON编码器,导致以原始JSON发送给服务器5c5c6e
,服务器尽职尽责地将其取消转义并将5c6e
存储在数据库/模型中。总之,您必须确定服务器在其模型/数据库中到底有什么,并弄清楚它是在服务器上存储模型数据的过程中还是在从服务器检索模型数据的过程中出现的bug。