好吧,我运行的数据是从我的PHP服务器提供的公共JSONP API。 我刚才读这篇文章:
- JSON:JavaScript的子集,是不是(由Magnus霍尔姆; 2011年5月)
(请阅读说明)
基本上,如果我的JSON字符串包含一个U + 2028字符(Unicode行分隔)或U + 2029字符(Unicode段落分隔),那么这是完全有效的JSON。 然而,使用JSONP当JSON被作为JavaScript的执行,在JavaScript中没有字符串可以包含文字U + 2028或U + 2029,因为它会打破的JavaScript。 显然,这通常不是一个问题,只要您使用合适的JSON分析器,但JSONP的情况下,浏览器是 JSON解析器。
从本质上讲,如果这些字符是在里面我JSONP数据串被发送到客户端,这将抛出一条线或段中断这将打破JavaScript和停止执行的字符串。 这是因为API正在发回一些客户端输入的数据的可能性。 有人可能会进入一个U + 2028或U + 2029到数据库中,所以当我发送回来的JSONP它会用我的API打破任何实现。
所以我的问题是,在PHP我怎么能消毒/输出逃避JSON数据它发送到客户端之前删除或逃避U + 2028和U + 2029个字符?
目前,我的过程是做了json_encode数据的阵列和发送数据到客户端。 我应该通过阵列循环并过滤它逸出数据,或者一次全部逸出所有的JSON编码的字符串?
另一件事是我不知道如何逃脱的U + 2028和U + 2029个字符在PHP中呢。 我可以做一个str_replace函数? 我不知道如果str_replace函数多字节安全,有没有mb_str_replace功能,除非我使用由一个一些自定义。 那么,你如何删除/逃生者Unicode字符?
非常感谢。
您可以替换U+2028
, U+2029
用"\u2028"
, "\u2029"
无论是在PHP端或JavaScript端,或两者兼而有之,这并不重要,只要它发生至少一次(它的幂等) 。
你可以使用普通的字符串替换功能。 他们并不需要“多字节安全”,你可以在任何Unicode编码(UTF-8,UTF-16,UTF-32都同样精)很容易地做到这一点。 PHP没有Unicode转义序列我最后一次检查是有一个理由,为什么PHP是一个笑话,但你可以使用\x
逃生用UTF-8 ...
(总之,究其原因有没有多字节字符串替换功能,是因为它是多余的 - 这将是完全一样的非多字节字符串替换功能。)
// Javascript
data = data.replace("\u2028", "\\u2028").replace("\u2029", "\\u2029");
// PHP
$data = str_replace("\xe2\x80\xa8", '\\u2028', $data);
$data = str_replace("\xe2\x80\xa9", '\\u2029', $data);
或者您也可以什么都不做,因为PHP逃脱非Unicode字符,在默认情况下json_encode()
// Safe
echo json_encode("\xe2\x80\xa9");
--> "\u2029"
// Correct JSON, but invalid Javascript...
// (Well, technically, JSON root must be array or object)
echo json_encode("\xe2\x80\xa9", JSON_UNESCAPED_UNICODE);
--> "
"
值得指出的是,这不再是必要的。
默认情况下, json_encode()
编码的所有非ASCII字符(包括U + 2028和U + 2029),也逃脱正斜杠,即使并不需要由JSON规范进行转义。 它没有伤害逃避它,并且它可以在某些情况下更安全。 因此,在默认情况下,这些字符转义反正。
所述JSON_UNESCAPED_UNICODE
恒定输出转义的Unicode,这可以节省字节。 然而,正如斜线字符转义,因为它可以在某些情况下危险的,所以太U + 2028和U + 2029 也逃脱了,因为他们也有在某些情况下的危险。 这不是你问你的问题时的情况: 该功能已经被添加到PHP更近 。
(这些额外的逃逸可与关闭JSON_UNESCAPED_SLASHES
和JSON_UNESCAPED_LINE_TERMINATORS
分别)。
文章来源: How to replace/escape U+2028 or U+2029 characters in PHP to stop my JSONP API breaking