解析JSON时出错,“Unescaped control character around character 981”。

14
我会尽力帮助您进行翻译。这是一个关于编程的错误信息,其中包含了未转义的控制字符“
”,出现在第981个字符周围。下面是相关代码行。
Alamofire.request(.POST, urlStr, parameters: parameter, encoding: .JSON, headers: nil).validate().responseJSON {
    response in switch response.result {

        case .Success(let JSON):
            completionHandler(JSON as! NSDictionary)

        case.Failure(let Error):

            print(Error)
    }
}

它会在Postman中返回JSON响应。
我在Postman中得到的响应:
{
  "orderdetails": {
    "status_code": "200",
    "status_message": "Order details",
    "billingandshipping": {
      "billing": {
        "firstname": "first",
        "lastname": "last",
        "email": "aa@bbb.com",
        "address": "dasdesfrew",
        "city": "Rajkot",
        "area": "University Road",
        "pincode": "360003",
        "phone": "1234567890",
        "mobileno": "1234567891"
      },
      "shipping": {
        "firstname": "first",
        "lastname": "last",
        "email": "aa@bbb.com",
        "address": "dasdesfrew",
        "city": "dasdesfrew",
        "area": "dcdc",
        "pincode": "360003",
        "phone": "1234567890",
        "mobileno": "1234567891"
      }
    },
    "orders": [
      {
        "order_id": "77",
        "order_date": "09-08-2016 13:05:29",
        "delivery_date": "10-08-2016",
        "order_items": [
          {
            "Sr": "1",
            "product_name": "Lemon",
            "gujtitle": "લીંબુ ",
            "product_code": "000057",
            "product_price": "108.00",
            "product_qty": "2",
            "unit": "1 kg.",
            "product_total": "216"
          }
        ],
        "final_total": "216.00",
        "shipping_cost": "0.00",
        "order_total": "216.00",
        "discount_type": "null",
        "discount_amount": "null",
        "coupon_name": "null",
        "comment": "gdhdj\nfghd.g\nghj\n\n\n\n\n\n\n\n\n\n.."
      }
    ]
  }
}

4
你的问题不在于代码,而是你的 JSON 不合法。 - Eric Aya
它在Postman中返回响应。 - Payal Maniyar
3
我并没有说没有响应,我是说JSON无效。 - Eric Aya
在 Postman 中添加您得到的响应!它可以是 JSON 字符串或普通字符串,与 JSON 对象不同。 - Ketan Parmar
问题是由于 \n 导致的。 - Payal Maniyar
显示剩余9条评论
5个回答

20

根据您所说,存在与“\n”相关的问题。

因此,我建议您可以添加“\\n”,像下面这样:

"\n"=> "\\n"

因为这是一个特殊字符,称为退格字符。


2
如果从服务器返回的JSON响应出现问题,并且特别是当你无法控制时(比如通过API),推荐的解决方法是什么?我遇到了类似的问题,而在我的某些尝试中,这解决了我的问题,但如果响应仍然被编码,我不确定是否能够替换所有响应。 - KSigWyatt
我遇到了其他字符'\r'的相同问题,我用'\r'替换了它。 - Afzaal Ahmad
@KSigWyatt(以及其他有疑问的人),如果使用URLSession(或类似于Alamofire的封装器),控制字符应该在需要时自动转义。您可以在完成处理程序中打印String(data: data, encoding: .utf8)来查看这一点。如果您正在模拟数据,则需要自己转义字符。 - froggomad

5
自从Swift 5发布以来,如果要在JSON字符串中添加\n字符,无需手动再加上一个\,而是可以使用原始字符串字面量声明,使用以下语法:

let jsonString = #"{"comment": "gdhdj\nfghd.g\nghj\n\n\n\n\n\n\n\n\n\n.."}"#

多行也可以:

let jsonString = #"""
{
  "comment": "gdhdj\nfghd.g\nghj\n\n\n\n\n\n\n\n\n\n.."
}
"""#

如果仅使用"""(不带#),上面的内容将会成功编译,但在运行时,下面使用JSONSerialization的例子将抛出错误。通过添加#"""可以修复该问题。

do {
    guard let data = jsonString.data(using: .utf8) else { throw SomeError() }
    let obj = try JSONSerialization.jsonObject(with: data)
    print("valid!")
} catch {
    print(error)
}

2

将你接收到的NSData打印出来,看看在第981个字节周围找到了什么。未转义控制字符的问题在于它们是不可见的,因此您无法在NSString中看到它们,但您可以在NSData中看到它们。

如果您的数据长度为981个字节或非常接近,则有可能您的代码处理了不完整的JSON数据,这几乎总是会失败的;这是需要修复的问题。如果在某些项之间(例如两个数组元素之间)存在控制字符,则可能是服务器代码中的错误。


1
我花了一些时间去弄清楚49546是什么意思。 如果您的问题是“字符 49546周围有未转义的控制字符”,请用\\\t替换\t

1

为了确保安全(因为人们常常复制/粘贴糟糕的代码...),我构建了一个安全的对象:

...

private final func fillWith(
     id: Int,
     name: String?
) {

    self.id = id
    self.productName = name?.replacingOccurrences(of: "\t", with: "")
    self.productName = self.productName?.replacingOccurrences(of: "\n", with: "")

发送 向上 没有问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接