10

我正在尝试将一些简单的 HTML 转换为 JSON 对象中的字符串值,但我无法让字符串编码不转义 NSJSONSerialization 中的字符串。

示例...我有一个包含一些基本 HTML 文本的字符串:

NSString *str = @"<html><body><p>Samples / Text</p></body></html>";

期望的结果是带有 HTML 作为值的 JSON:

{
    "Title":"My Title",
    "Instructions":"<html><body><p>Samples / Text</p></body></html>"
}

我正在使用标准技术将 NSDictionary 转换为包含 JSON 的 NSString:

NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:str forKey:@"Instructions"];
[dict setObject:@"My Title" forKey:@"Title"];

NSError *err;
NSData *data = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:&err];
NSString *resultingString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@", resultingString);

此方法生成的 JSON 是有效的,但是 HTML 已转义所有正斜杠:

{
    "Title":"My Title",
    "Instructions":"<html><body><p>Samples \/ Text<\/p><\/body><\/html>"
}

这会在说明 JSON 字符串中创建无效的 HTML。

我想坚持使用 NSJSONSerialization,因为我们在框架中的其他任何地方都使用它,并且在切换到非 Apple 库之前我已经被烧毁了,因为它们被取消支持。我尝试了许多不同的字符串编码,它们都避开了尖括号。

显然 \/ 是 JavaScript 中 / 字符的有效表示,这就是转义正斜杠的原因(甚至 StackOverflow 文本编辑器也转义了它)。请参阅: 使用正斜杠转义 json 字符串? 还有JSON:为什么要转义正斜杠?. 我只是不希望它这样做,而且似乎没有办法阻止 iOS 在序列化时转义字符串值中的正斜杠。

4

3 回答 3

4

我相信NSJSONSerialization在编码 HTML 方面的行为符合设计。

如果您查看一些关于在 JSON 中编码 HTML 的问题(1、2 ,您会看到答案总是提到转义正斜杠。

JSON不需要转义正斜杠,但 HTML 不允许包含 javascript 字符串,因为它可能与标记</的结尾混淆。<SCRIPT>

请参阅此处此处以及最直接的w3.org HTML4 附录中的答案,该附录在B.3.2 中指定非 HTML 数据

ILLEGAL EXAMPLE: 
The following script data incorrectly contains a "</" sequence (as part of "</EM>") before the SCRIPT end tag:

<SCRIPT type="text/javascript">
  document.write ("<EM>This won't work</EM>")
</SCRIPT>

尽管此行为可能会给您带来问题,但您只是在遵循编码 HTML 数据以用于标签NSJSONSerialisation的古老规则。<SCRIPT>

于 2013-12-08T00:14:39.990 回答
0

这是我在生成的 JSONAFJSONRequestSerializer中删除符号\之前的子类;/如果你使用 AFNetworking 会很方便

class SanitizedAFJSONRequestSerializer: AFJSONRequestSerializer
{
    override func requestBySerializingRequest(request: NSURLRequest!, withParameters parameters: AnyObject!, error: NSErrorPointer) -> NSURLRequest!
    {
        var request = super.requestBySerializingRequest(request, withParameters: parameters, error: error)

        if let jsonData = request.HTTPBody
        {
            if let jsonString = NSString(data: jsonData, encoding: NSUTF8StringEncoding) as? String
            {
                let sanitizedString = jsonString.stringByReplacingOccurrencesOfString("\\/", withString: "/", options: NSStringCompareOptions.CaseInsensitiveSearch, range:nil) as NSString

                println("sanitized json string: \(sanitizedString)")

                var mutableRequest = request.mutableCopy() as! NSMutableURLRequest
                mutableRequest.HTTPBody = sanitizedString.dataUsingEncoding(NSUTF8StringEncoding)
                request = mutableRequest
            }
        }

        return request
    }
}
于 2015-06-12T12:03:30.873 回答
0

仅限 iOS 13: 如果您不担心产生无效的 HTML 序列(如本答案中所述),您可以通过将选项传递NSJSONWritingWithoutEscapingSlashes给序列化程序来禁用正斜杠转义。

例子:

jsonData = [NSJSONSerialization dataWithJSONObject:batchUpdates
                                           options:NSJSONWritingWithoutEscapingSlashes
                                             error:nil];
于 2020-02-06T19:41:37.450 回答