简体   繁体   English

为什么我不必在JS中解码/解析PHP生成的JSON字符串

[英]Why don't I have to decode/parse a JSON string generated by PHP in JS

To use some variables in a JS script, I simply set them in a wrapper with JSON, like so: 要在JS脚本中使用一些变量,我只需在JSON包装器中设置它们,如下所示:

<?php // Variables for JS
$vars = array(
    'fetchPath' => "$home/my-url.php",
);
?>
<script>
var phpVars = <?php echo json_encode($vars); ?>;
</script>

This results in 这导致

<script>
var phpVars = {"fetchPath":"http:\/\/my.website.com\/my-url.php"};
</script>

Now, when I try to parse this value from a JS script, I get an unexpected token error. 现在,当我尝试从JS脚本解析此值时,出现意外的令牌错误。 But, when I simply use the variable as if it were an object, it works perfectly. 但是,当我简单地使用变量作为对象时,它就可以完美地工作。 In other words, I can simply access phpVars.fetchPath without having converted that value back to an object representation. 换句话说,我可以简单地访问phpVars.fetchPath而无需将该值转换回对象表示形式。

Am I completely losing my mind after hours of working with Perl, PHP, and Javascript, and you don't have to decode a JSON string in JS - or is something else going on? 在使用Perl,PHP和Javascript几个小时后,我是否完全失去了理智,而您不必在JS中解码JSON字符串-还是发生了其他事情?

That's what JSON is all about: it's the JavaScript Object Notation - a format that's being natively understood by JavaScript. 这就是JSON的全部含义:这是JavaScript对象表示法 -一种JavaScript本来可以理解的格式。

var json = {"a": 1, "b": false, "c": null, "d": [1, 2, 3], "e": {"f": 1}};

is perfectly valid JavaScript and that's what the PHP json_encode function produces out of the following structure for example: 是完全有效的JavaScript,这就是PHP json_encode函数根据以下结构产生的结果:

$json = array(
    'a' => 1, 
    'b' => false, 
    'c' => null, 
    'd' => array(1, 2, 3), 
    'e' => array(
        'f' => 1
    )
);

You'd need parseJSON if you retrieve the string '{"a": 1, "b": false, "c": null, "d": [1, 2, 3], "e": {"f": 1}}' from an XMLHttpRequest (aka AJAX) request. 如果您检索字符串 '{"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)请求。 The response body will be a string and this needs to be converted into a JavaScript object by using parseJSON . 响应主体将是一个字符串,需要使用parseJSON将其转换为JavaScript对象。 That's just one example. 那只是一个例子。 Opening a JSON file in nodejs is another one. 在nodejs中打开JSON文件是另一个。

In your example you literally embedded the json_encode output into some JavaScript source (defined by the <script> tags). 在您的示例中,您实际上将json_encode输出嵌入到某些JavaScript源(由<script>标记定义)中。 That's why the JavaScript interpreter catches up the JSON-syntax and constructs a JavaScript object from it. 这就是JavaScript解释器追上JSON语法并从中构造JavaScript对象的原因。

When you do this: 执行此操作时:

<script>
var phpVars = <?php echo json_encode($vars); ?>;
</script>

you're generating JavaScript code with PHP. 您正在使用PHP生成JavaScript代码。 So what actually goes to your browser is: 因此,实际进入浏览器的是:

<script>
var phpVars = /*...THE_JSON_GOES_HERE...*/;
</script>

Note that it's not in quotes or anything. 请注意,它不是用引号引起来的。 Your example code will produce a JSON string that looks something like {"fetchPath":"/path/to/my-url.php"} , so what the browser would see is: 您的示例代码将生成一个类似于{"fetchPath":"/path/to/my-url.php"}的JSON字符串,因此浏览器将看到:

<script>
var phpVars = {"fetchPath":"http:\/\/my.website.com\my-url.php"};
</script>

Since JSON is a subset of JavaScript object initializer syntax, that's perfectly valid JavaScript code. 由于JSON是JavaScript对象初始化程序语法的子集,因此这是完全有效的JavaScript代码。 The parser parsing the script tag contents parses it as code , not as JSON. 解析脚本标签内容的解析器将其解析为代码 ,而不是JSON。 But that's fine, because as long as it's used as a right-hand value (eg, on the right-hand side of = or passed into a function, etc.), JSON is valid JavaScript. 但这很好,因为只要将其用作右侧值(例如,在=的右侧或传递给函数等),JSON就是有效的JavaScript。

JSON was modeled after the syntax for JavaScript literals. JSON是根据JavaScript文字的语法建模的。

When you take some JSON and drop it into the middle of a JavaScript program as if it were JavaScript code, then it is treated as JavaScript code and parsed as a set of JavaScript literals. 当您使用一些JSON并将其放入JavaScript程序的中间,就好像它是JavaScript代码一样,那么它将被视为JavaScript代码并被解析为一组JavaScript文字。

In which cases, then, do you need parseJSON 那么,在这种情况下,您是否需要parseJSON

When you get JSON in a format that is not JavaScript code (such as when you fetch a JSON resource over HTTP with XMLHttpRequest), it is put in a string. 当您以非JavaScript代码的格式获取JSON时(例如,当您使用XMLHttpRequest通过HTTP获取JSON资源时),它将被放入一个字符串中。 You need to convert the JSON into JavaScript objects explicitly then. 然后,您需要将JSON明确转换为JavaScript对象。

A few terms that are not always clear: 一些并不总是很清楚的术语:

  • PHP and JavaScript are different languages and do not interact directly: they don't share variables, they don't share resources of any kind... they don't even run on the same computer! PHP和JavaScript是不同的语言,并且不直接交互:它们不共享变量,不共享任何类型的资源……甚至不在同一台计算机上运行! PHP runs on the server (let's say, a DELL computer somewhere in Google data center in Ireland) and JavaScript runs inside the browser (let's say, granny's laptop near Munich). PHP在服务器上运行(例如,爱尔兰Google数据中心某处的DELL计算机),而JavaScript在浏览器中运行(例如,慕尼黑附近的Granny的笔记本电脑)。

    You often use PHP to generate JavaScript code. 您经常使用PHP生成JavaScript代码。 The browser doesn't know or care about how that code is generated: it merely sees the generated source code—and show should you: with your browser's View Source feature (typically mapped to the Ctrl + U short-cut). 浏览器不知道或不关心该代码的生成方式:它仅查看生成的源代码,并通过浏览器的“ 查看源代码”功能(通常映射到Ctrl + U快捷键)显示给您看。

  • JavaScript and JSON are different languages and could hardly have less capabilities in common. JavaScript和JSON是不同的语言,几乎没有共同的功能。 JavaScript is a programming language and JSON is a data format. JavaScript是一种编程语言,而JSON是一种数据格式。 The only relation is that JSON creator has the idea of basing his language in a (very limited) subset of the JavaScript syntax. 唯一的关系是JSON创建者的想法是将其语言基于JavaScript语法的(非常有限的)子集。 That witty idea allowed to read properly formatted JSON from JavaScript code by using the eval() function—in other words, he invented a new format and he didn't have to write a parser! 这个机智的想法允许通过使用eval()函数从JavaScript代码中读取格式正确的JSON,换句话说,他发明了一种新格式,而不必编写解析器!

    (Of course, nobody uses eval() any more and as JSON became popular everybody has written proper parsers anyway.) (当然,没有人再使用eval()了,并且随着JSON的流行,每个人都已经编写了适当的解析器。)

And one more detail... The PHP function to generate JSON actually allows to generate partial JSON , which technically speaking is not valid 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\""

That trick is often "abused" to inject raw input into generated JavaScript code because there's otherwise no simple way to avoid causing parse errors if your data happens to contain characters that have a special meaning inside JavaScript syntax: 该技巧通常被“滥用”以将原始输入注入到生成的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)

Simple answer: 简单答案:

You are not using quotes 您没有使用引号

This is first parsed by PHP, server side, so whatever is within php tags will be rendered and returned to the browser (which is the one that parses javascript): 这是首先由PHP在服务器端进行解析的,因此php标记中的所有内容都将呈现并返回到浏览器(解析javascript的浏览器):

<script>
var phpVars = <?php echo json_encode($vars); ?>;
</script>

The resulting text, ON THE BROWSER would be: 浏览器上的结果文本为:

<script>
var phpVars = {"foo": "bar"};
</script>

If you were using quotes... 如果您使用引号...

<script>
var phpVars = <?php echo "'" . json_encode($vars) . "'" ; ?>;
</script>

That would turn into the following html on the browser: 那将在浏览器中变成以下html:

<script>
var phpVars = '{"foo": "bar"}';
</script>

Then in the above case you would need to parse the result because is just simply a string: 然后在上述情况下,您将需要分析结果,因为它只是一个字符串:

<script>
var phpVars = '{"foo": "bar"}';
vars = JSON.parse(phpVars);
//vars is now a JS valid object
</script>

So the answer is that your php is echoing a text that will not be actually represented a string in JS but as an object notation object. 因此,答案是您的php回显了一个文本,该文本实际上不会在JS中表示为字符串,而是作为对象表示法对象。 JSON.parse is used to process a string representation of a valid JS value (an array, an object, number, etc.) JSON.parse用于处理有效JS值的字符串表示形式(数组,对象,数字等)

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

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