繁体   English   中英

为什么我不必在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字符串-还是发生了其他事情?

这就是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
    )
);

如果您检索字符串 '{"a": 1, "b": false, "c": null, "d": [1, 2, 3], "e": {"f": 1}}'则需要parseJSON '{"a": 1, "b": false, "c": null, "d": [1, 2, 3], "e": {"f": 1}}'来自XMLHttpRequest(aka AJAX)请求。 响应主体将是一个字符串,需要使用parseJSON将其转换为JavaScript对象。 那只是一个例子。 在nodejs中打开JSON文件是另一个。

在您的示例中,您实际上将json_encode输出嵌入到某些JavaScript源(由<script>标记定义)中。 这就是JavaScript解释器追上JSON语法并从中构造JavaScript对象的原因。

执行此操作时:

<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文字。

那么,在这种情况下,您是否需要parseJSON

当您以非JavaScript代码的格式获取JSON时(例如,当您使用XMLHttpRequest通过HTTP获取JSON资源时),它将被放入一个字符串中。 然后,您需要将JSON明确转换为JavaScript对象。

一些并不总是很清楚的术语:

  • PHP和JavaScript是不同的语言,并且不直接交互:它们不共享变量,不共享任何类型的资源……甚至不在同一台计算机上运行! PHP在服务器上运行(例如,爱尔兰Google数据中心某处的DELL计算机),而JavaScript在浏览器中运行(例如,慕尼黑附近的Granny的笔记本电脑)。

    您经常使用PHP生成JavaScript代码。 浏览器不知道或不关心该代码的生成方式:它仅查看生成的源代码,并通过浏览器的“ 查看源代码”功能(通常映射到Ctrl + U快捷键)显示给您看。

  • JavaScript和JSON是不同的语言,几乎没有共同的功能。 JavaScript是一种编程语言,而JSON是一种数据格式。 唯一的关系是JSON创建者的想法是将其语言基于JavaScript语法的(非常有限的)子集。 这个机智的想法允许通过使用eval()函数从JavaScript代码中读取格式正确的JSON,换句话说,他发明了一种新格式,而不必编写解析器!

    (当然,没有人再使用eval()了,并且随着JSON的流行,每个人都已经编写了适当的解析器。)

还有一个更多的细节... 生成JSONPHP函数实际上允许生成部分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值的字符串表示形式(数组,对象,数字等)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM