当涉及转义字符时,Javascript eval 无法评估 json

标签 javascript json eval rhino

我正在使用 rhino javascript 引擎来评估 json。 Json结构如下:

{"DataName":"111","Id":"222","Date":"2015-12-31T00:00:00","TextValue":"{\"Id\":\"1\",\"Name\":\"Daugherty\",\"ContactName\":\"May C\",\"ContactEmail\":\"may.c@gamil.com\",\"Total\":25,\"Phone\":\"111-111-1111\",\"Type\":\"Daily\",\"Notes\":[{\"Comments\":\"One\",\"Date\":\"2014-11-27T00:00:00.000\"},{\"Comments\":\"Two\",\"Date\":\"2014-11-28T00:00:00.000\"}],\"ImportComplete\":true,\"RunComplete\":true,\"CompleteDate\":\"2014-07-31T00:00:00.000\",\"Amount\":2400.00,\"ProcessingComplete\":true}","NumberValue":4444.5555,"DateValue":"2014-12-01T00:00:00"}

由于我使用的是 Rhino js 引擎,所以我无法使用 JSON.parse 和 JSON.stringify。 正如你所看到的,json 嵌入了 json,这个 json 是我从 .net web api 获取的,它放置了转义字符“\”。我正在尝试替换 javascript 中的转义字符,但没有帮助。

在 JavaScript 中是否有任何方法可以替换该转义字符并使用“eval()”来计算 json。

这是我正在尝试的代码

var json = '{"DataName":"111","Id":"222","日期":"2015-12-31T00:00:00","TextValue":"{\"Id\":\"1\",\"姓名\":\"Daugherty\",\"联系人姓名\":\"May C\",\"联系人电子邮件\":\"may.c@gamil.com\",\"总数\":25,\"电话\":\"111-111-1111\",\"类型\":\"每日\",\"备注\":[{\"评论\":\"一\",\"日期\":\"2014-11-27T00:00:00.000\"},{\"评论\":\"二\",\"日期\":\"2014 -11-28T00:00:00.000\"}],\"ImportComplete\":true,\"RunComplete\":true,\"CompleteDate\":\"2014-07-31T00:00:00.000\",\"金额\":2400.00,\"处理完成\":true}","NumberValue":4444.5555,"DateValue":"2014-12-01T00:00:00"}';

var find = '\"';

var regex = new RegExp(find,'g');

var inj = json.replace(regex,'"');

var pl = eval('(' + inj +')');

最佳答案

令人困惑的反斜杠

当您的“字符串”深度超过一层时,您遇到的问题是由于没有完全理解转义字符。虽然单个斜杠对于一个级别来说就可以了,即:

"It is no coincidence that in no known language does the " + 
"phrase \"As pretty as an Airport\" appear.";

如果您将其放在外引号中:

'"It is no coincidence that in no known language does the "' + 
'"phrase \"As pretty as an Airport\" appear."';

反斜杠(如果解析字符串的系统支持作为转义字符)适用于最外层的换行引号,而不是像以前那样适用于任何内部引号/字符串。这意味着一旦 js 引擎解析了字符串,该字符串就会在内部被解析。

'"It is no coincidence that in no known language does the phrase "As pretty as an Airport" appear."';

这使得无法区分原始字符串中的 "\" 。为了解决这个问题,您需要在换行之前转义原始字符串中的反斜杠。这会导致 JavaScript 引擎使用一级转义,但在字符串中仍保留另一级转义。例如

'"It is no coincidence that in no known language does the "' + 
'"phrase \\"As pretty as an Airport\\" appear."';

现在,当解析字符串时,内部它将是:

'"It is no coincidence that in no known language does the phrase \"As pretty as an Airport\" appear."';

ignore the my random Douglas Adams quotes being separated onto more than one line (using +), I've only done that for ease of reading within a fix width area. I've kept it parsable by JavaScript, just in case people copy and paste and expect things to work.

因此,为了解决您的问题,您的 JSON 源(在放入 JavaScript 代码之前)必须如下所示:

var json = '{"DataName":"111","Id":"222","Date":"2015-12-31T00:00:00","TextValue":"{\\"Id\\":\\"1\\",\\"Name\\":\\"Daugherty\\",\\"ContactName\\":\\"May C\\",\\"ContactEmail\\":\\"may.c@gamil.com\\",\\"Total\\":25,\\"Phone\\":\\"111-111-1111\\",\\"Type\\":\\"Daily\\",\\"Notes\\":[{\\"Comments\\":\\"One\\",\\"Date\\":\\"2014-11-27T00:00:00.000\\"},{\\"Comments\\":\\"Two\\",\\"Date\\":\\"2014-11-28T00:00:00.000\\"}],\\"ImportComplete\\":true,\\"RunComplete\\":true,\\"CompleteDate\\":\\"2014-07-31T00:00:00.000\\",\\"Amount\\":2400.00,\\"ProcessingComplete\\":true}","NumberValue":4444.5555,"DateValue":"2014-12-01T00:00:00"}';

您应该会发现上面的内容将直接eval,而不进行任何替换。

为了以编程方式实现上述目标,您必须了解您使用的 .NET 系统以转义反斜杠的方式提供了什么。我主要在服务器端使用 PHP 或 Python。使用您可以使用的语言:

the $s and s strings below have been cropped for brevity.

<?php
$s = '{"DataName":"111","Id":"222"...';
$s = str_replace("\\", "\\\\", $s);
echo "var json = '$s';";

或者...

#!/usr/bin/env python
s = r'{"DataName":"111","Id":"222"...'
s = s.replace("\\", "\\\\")
print "var json = '" + s + "';"


另一种解决方案

这完全取决于您如何请求在 JavaScript 中包装在字符串中的内容。如果你有能力从服务器端写出你的js(最有可能使用.NET)。就像我上面用 PHP 或 Python 展示的那样,您根本不需要将内容包装在字符串中。您可以只输出内容而不用单引号括起来。然后 JavaScript 将解析它并将其视为文字对象结构:

var jso = {"DataName":"111","Id":"222","Date":"2015-12-31T00:00:00","TextValue":"{\"Id\":\"1\",\"Name\":\"Daugherty\",\"ContactName\":\"May C\",\"ContactEmail\":\"may.c@gamil.com\",\"Total\":25,\"Phone\":\"111-111-1111\",\"Type\":\"Daily\",\"Notes\":[{\"Comments\":\"One\",\"Date\":\"2014-11-27T00:00:00.000\"},{\"Comments\":\"Two\",\"Date\":\"2014-11-28T00:00:00.000\"}],\"ImportComplete\":true,\"RunComplete\":true,\"CompleteDate\":\"2014-07-31T00:00:00.000\",\"Amount\":2400.00,\"ProcessingComplete\":true}","NumberValue":4444.5555,"DateValue":"2014-12-01T00:00:00"};

这之所以有效,是因为 JSON 只是 JavaScript 对象的更严格版本,并且您已有的引用/转义级别可以正常工作。

The only downside to the above solution is that you have to implicitly trust the source of where you are getting this data from, and it will always have to be well formed. If not, you could introduce parse errors or unwanted js into your code; which could be avoided with an eval/JSON.parse system.

关于当涉及转义字符时,Javascript eval 无法评估 json,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31825748/

相关文章:

perl - 使用 Perl 的 eval 时常见的陷阱是什么?

javascript - 有什么方法可以自动增加 firebase 中的字段

javascript - 将跨度添加到标签 ID

javascript - 按等级创建新的对象数组

json - 将 JSON 文件导入 Firebase 错误

php - PHP eval 的限制

javascript - JS : using eval on a function while trying to pass an array as parameter, 但它抛出一个错误

javascript 窗帘(用于指示繁忙的进程)未显示整个进程。可能我对回调的理解不够

javascript - 如何使用 jquery 从 radio 输入中获取数据值?

json - ConvertFrom-Json 将小写 e 转换为大写字母(有时)