Swift解码含双引号URL的JSON时报错 如何处理用户输入的双引号?
问题原因
你遇到的两个报错分别对应两个不同的层级错误:
- JSON语法错误:你当前手动拼接的JSON字符串中,URL内部的双引号没有完成JSON要求的转义。Swift的多行字符串里写的
\"会被Swift首先解析为普通双引号,最终生成的JSON内容里URL直接携带未转义的双引号,破坏了JSON字符串的闭合规则,所以抛出JSON无效错误。 - URL格式错误:即使JSON转义正确,URL标准RFC 3986明确禁止未编码的双引号出现在URL中,
JSONDecoder将字符串转为URL类型时会直接抛出无效URL错误。
解决方案
分两个层级处理,优先处理URL编码,再保证JSON转义正确:
- 首先对用户输入的URL部分做百分编码
双引号的百分编码值为%22,所有用户输入的URL路径段、查询参数都要做百分编码后再拼接为完整URL,避免出现非法URL字符。 - 不要手动拼接JSON,使用
JSONEncoder生成JSON内容JSONEncoder会自动处理字符串中的特殊字符转义,完全避免手动转义的疏漏。
修正后的代码示例
import Foundation // 第一步:处理用户输入,做百分编码 let userInputFilename = #"1-test_Romio's-"Video-"# // 用户输入包含双引号 // 对用户输入的路径段做百分编码,自动转义双引号、空格等非法URL字符 let encodedFilename = userInputFilename.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)! let fullUrlString = "https://somedomain.come/folder/\(encodedFilename)?hl=en-GB" // 第二步:用JSONEncoder生成JSON,自动处理转义 struct Model: Codable { let contentUrl: URL } let model = Model(contentUrl: URL(string: fullUrlString)!) do { // 编码得到JSON Data,传输、存储直接用这个Data即可 let jsonData = try JSONEncoder().encode(model) // 解码验证 let decoder = JSONDecoder() let decodedObject = try decoder.decode(Model.self, from: jsonData) print(decodedObject.contentUrl) // 输出:https://somedomain.come/folder/1-test_Romio's-%22Video-?hl=en-GB } catch { print(error) }
特殊场景兼容
如果你无法控制JSON生成逻辑,只能拿到包含未转义双引号的JSON字符串,可以先对JSON字符串做预处理,匹配URL字段内部的双引号做转义后再解码,不过这种方案稳定性差,优先推荐从生成侧按照上述方案修正。
内容的提问来源于stack exchange,提问作者Marwan
相关产品推荐
相关产品推荐

