为啥使用 JSON.parse(decodeURIComponent(staticString))?
Posted
技术标签:
【中文标题】为啥使用 JSON.parse(decodeURIComponent(staticString))?【英文标题】:Why use JSON.parse(decodeURIComponent(staticString))?为什么使用 JSON.parse(decodeURIComponent(staticString))? 【发布时间】:2016-03-21 01:00:29 【问题描述】:某些动态 Web 框架使用此代码片段
<script>
appSettings = JSON.parse(
decodeURIComponent(
"%7B%22setting1%22%3A%22foo%22%2C%22setting2%22%3A123%7D"));
</script>
他们试图用这段代码解决一个标准的 html5/javascript 问题吗?为什么不只是
<script>
appSettings = "setting1":"foo","setting2":123;
</script>
注意:这是动态生成的代码。我假设在服务器上他们正在做类似的事情
var settingsString = encodeURIComponent(JSON.stringify(settings));
var output = '<script>appSettings=JSON.parse(decodeURIComponent("' +
settingsString +
'"));</script>';
但它似乎也可以像这样工作
var settingsString = JSON.stringify(settings);
var output = '<script>appSettings=' +
settingsString +
';</script>';
一个想法是后者可以包含代码,但它们是提供字符串的人,它不是用户数据,所以它们不可能是代码。加上在服务器上使用JSON.stringify
将删除所有代码。即使在客户端上,JSON.parse
的 JSON.stringify
ied 对象的简单 JSON.parse
也会阻止代码。
三重解析是否解决了具体问题?一次使用 JavaScript,一次使用 decodeURIComponent,一次使用 JSON.parse?
这不是一个基于意见的问题
问题是要解决什么问题。要么有问题正在解决,要么没有。回答这个问题不需要任何意见。例如,如果 JSON.stringify 有时碰巧发出无法解析的代码(据我所知,它不会,但如果有人知道得更好,那么这将是一个很好的答案)。
另请注意:我不是在问他们的框架为什么这样做。我在问标准 HTML5/JavaScript 中是否存在真正的问题正在解决。换句话说,我是否应该采用这种模式,因为如果我不这样做,我总有一天会遇到问题。
【问题讨论】:
我能想到为什么有人可能这样做的各种原因(虽然我能想到 (FSVO) 更好的方法来解决同样的问题),但你要求我们推测未知人的思维过程,这实际上是无法回答的。 @Quentin,不,我不是要你推测。要么有具体的客观原因,要么没有。这就是问题所在。它的具体客观原因是什么。解决什么问题。 AFAIK JSON 没有转义问题,因此三重解析是多余的。但我可能错了,所以这个问题。 您是否有理由拒绝提及执行此操作的框架?这将有助于找出原因。 这种编码的一个好处是如果你的 JSON 包含 HTML(例如关闭</script>
标签),浏览器会将其解释为 HTML。
@gman:告诉我们框架的名称可以让我们检查其来源并寻找确定的 cmets。
【参考方案1】:
三重解析是否解决了具体问题?
是的。您建议的解决方案有两个问题:
它被解析为 HTML。</script>
之类的内容可能会对内联脚本造成严重破坏。
它被解析为 JS。 Not all JSON strings are valid JS literals。
decodeURIComponent
+ JSON.parse
方法是一种粗略的解决方法,但看起来更像是一种快速修复而不是适当的解决方案。
【讨论】:
您能否详细说明为什么它是快速修复而不是适当的解决方案? 它不必要地扩大了大小,一次是为了将 JSON 嵌入到 JS 字符串中,一次是为了对所有内容进行 url 编码。只需转义有问题的字符(序列)就足够了。【参考方案2】:@katspaugh 是正确的
测试
var settingString = JSON.stringify(
"</script>": "<script>bar=123</script>",
);
将上述示例的代码生成为
<script>
appSettings = "</script>":"<script>window.bar=123</script>"
</script>
无法解析为 HTML。在服务器上添加encodeURIComponent
JSON.parse(decodeURIComponent(...))
在客户端上修复该问题
【讨论】:
以上是关于为啥使用 JSON.parse(decodeURIComponent(staticString))?的主要内容,如果未能解决你的问题,请参考以下文章
为啥使用 JSON.parse(decodeURIComponent(staticString))?
为啥 JSON.parse(['1234']) 返回 1234?
为啥 JSON.parse(['1234']) 返回 1234?
JSON.parse(message) 失败,但“https://jsonlint.com/”显示消息有效。为啥会这样?