为什么我不必在 JS 中解码/解析 PHP 生成的 JSON 字符串
Why don't I have to decode/parse a JSON string generated by PHP in JS
要在JS脚本中使用一些变量,我只需将它们设置在带有JSON的包装器中,如下所示:
<?php // Variables for JS
$vars = array(
'fetchPath' => "$home/my-url.php",
);
?>
<script>
var phpVars = <?php echo json_encode($vars); ?>;
</script>
这导致
<script>
var phpVars = {"fetchPath":"http:'/'/my.website.com'/my-url.php"};
</script>
现在,当我尝试从 JS 脚本解析此值时,我收到意外的令牌错误。但是,当我简单地将变量用作对象时,它可以完美地工作。换句话说,我可以简单地访问phpVars.fetchPath
,而无需将该值转换回对象表示形式。
在使用Perl,PHP和Javascript数小时后,我是否完全失去了理智,并且您不必在JS中解码JSON字符串 - 还是发生了其他事情?
当你这样做时:
<script>
var phpVars = <?php echo json_encode($vars); ?>;
</script>
你正在用PHP生成JavaScript代码。因此,实际进入浏览器的是:
<script>
var phpVars = /*...THE_JSON_GOES_HERE...*/;
</script>
请注意,它不在引号或任何内容中。您的示例代码将生成一个看起来像 {"fetchPath":"/path/to/my-url.php"}
的 JSON 字符串,因此浏览器将看到的是:
<script>
var phpVars = {"fetchPath":"http:'/'/my.website.com'my-url.php"};
</script>
由于 JSON 是 JavaScript 对象初始值设定项语法的子集,因此这是完全有效的 JavaScript 代码。解析脚本标记内容的解析器将其解析为代码,而不是 JSON。但这没关系,因为只要它用作右侧值(例如,在=
的右侧或传递到函数等),JSON 就是有效的 JavaScript。
JSON 是根据 JavaScript 文字的语法建模的。
当你把一些JSON放到JavaScript程序的中间,就好像它是JavaScript代码一样,那么它就被视为JavaScript代码,并被解析为一组JavaScript文字。
那么,在哪些情况下,您是否需要解析JSON
当您以非 JavaScript 代码的格式获取 JSON 时(例如,当您使用 XMLHttpRequest 通过 HTTP 获取 JSON 资源时),它会放在一个字符串中。然后,您需要将 JSON 显式转换为 JavaScript 对象。
这就是JSON的全部意义所在:它是JavaScript对象表示法 - 一种被JavaScript原生理解的格式。
var json = {"a": 1, "b": false, "c": null, "d": [1, 2, 3], "e": {"f": 1}};
是完全有效的JavaScript,这就是PHP json_encode
函数从以下结构中产生的,例如:
$json = array(
'a' => 1,
'b' => false,
'c' => null,
'd' => array(1, 2, 3),
'e' => array(
'f' => 1
)
);
如果您从 XMLHttpRequest(又名 AJAX)请求中检索字符串'{"a": 1, "b": false, "c": null, "d": [1, 2, 3], "e": {"f": 1}}'
,则需要parseJSON
。响应正文将是一个字符串,需要使用 parseJSON
将其转换为 JavaScript 对象。这只是一个例子。在nodejs中打开JSON文件是另一个。
在您的示例中,您实际上将json_encode
输出嵌入到某个 JavaScript 源代码(由 <script>
标记定义)。这就是为什么 JavaScript 解释器会追上 JSON 语法并从中构造一个 JavaScript 对象。
一些并不总是清楚的术语:
-
PHP 和 JavaScript 是不同的语言,不直接交互:它们不共享变量,不共享任何类型的资源......它们甚至不在同一台计算机上运行!PHP在服务器上运行(假设,爱尔兰Google数据中心某处的DELL计算机),JavaScript在浏览器中运行(假设,慕尼黑附近的奶奶的笔记本电脑)。
你经常使用 PHP 来生成 JavaScript 代码。浏览器不知道也不关心代码是如何生成的:它只看到生成的源代码,并显示是否应该:使用浏览器的"查看源代码"功能(通常映射到Ctrl+U 快捷方式)。
-
JavaScript和JSON是不同的语言,几乎没有共同的功能。JavaScript是一种编程语言,JSON是一种数据格式。唯一的关系是JSON创建者的想法是将他的语言基于JavaScript语法的(非常有限的)子集。这个机智的想法允许使用
eval()
函数从 JavaScript 代码中读取正确格式的 JSON——换句话说,他发明了一种新格式,他不必编写解析器!(当然,没有人再使用
eval()
了,随着JSON的流行,每个人都编写了正确的解析器。
还有一个细节...生成JSON的PHP函数实际上允许生成部分JSON,从技术上讲,这不是有效的JSON:
echo json_encode(array('A', 'B')); // Valid JSON: ["A","B"]
echo json_encode('Leopoldo Alas "Clarín"'); // JSON fragment: "Leopoldo Alas '"Clar'u00edn'""
这个技巧经常被"滥用",将原始输入注入到生成的 JavaScript 代码中,因为如果你的数据碰巧包含 JavaScript 语法中具有特殊含义的字符,则没有简单的方法来避免导致解析错误:
<?php
$writer = 'Leopoldo Alas "Clarín"';
?>
var writer = "<?php echo $writer; ?>";
var writer = "Leopoldo Alas "Clarín"";
^^^^^^
SyntaxError: Unexpected identifier
at Object.exports.runInThisContext (vm.js:53:16)
at Object.<anonymous> ([stdin]-wrapper:6:22)
at Module._compile (module.js:413:34)
at node.js:544:27
at _combinedTickCallback (node.js:370:9)
at process._tickCallback (node.js:401:11)
简单的答案:
您没有使用引号
这首先由服务器端的 PHP 解析,因此 php 标签中的任何内容都将被渲染并返回到浏览器(这是解析 javascript 的浏览器):
<script>
var phpVars = <?php echo json_encode($vars); ?>;
</script>
在浏览器上生成的文本将是:
<script>
var phpVars = {"foo": "bar"};
</script>
如果您使用的是引号...
<script>
var phpVars = <?php echo "'" . json_encode($vars) . "'" ; ?>;
</script>
这将在浏览器上变成以下 html:
<script>
var phpVars = '{"foo": "bar"}';
</script>
那么在上面的情况下,你需要解析结果,因为只是一个字符串:
<script>
var phpVars = '{"foo": "bar"}';
vars = JSON.parse(phpVars);
//vars is now a JS valid object
</script>
所以答案是你的 php 正在回显一个文本,该文本实际上不会在 JS 中表示为字符串,而是作为对象表示法对象。JSON.parse 用于处理有效 JS 值(数组、对象、数字等)的字符串表示形式。
- 我们可以将ng绑定值存储到php字符串中吗
- 传递php字符串作为php脚本中调用的javascript函数的参数
- 简单的PHP字符串检查不起作用
- PHP字符串到json数组
- 如何传递PHP字符串作为JS函数参数
- 使用爆炸将php字符串转换为数组,需要在javascript中帮助操作
- PHP 字符串正在将空格更改为 + 符号.需要解码以保留空格
- 将 PHP 字符串传递给 JavaScript 函数
- 简单的php字符串问题(HTML和javascript)
- 来自 php 字符串的动态链接
- Javascript PHP 字符串未返回所需的结果
- 使用 JavaScript 实现 PHP 字符串异或
- 如何放置 PHP 字符串 jQuery 验证错误消息
- 将 php 字符串作为 json 传递,以便由 jquery 接收
- 提取 php 字符串中以 $ 开头的单词
- 将javascript输入转换为php字符串
- PHP 字符串包含打印 Javascript 时的换行符问题
- 在javascript中放一个php字符串
- 我想将这个echo块中php字符串的值大写
- jquery$.parseXML无法从php字符串中解析XML