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

时间:2016-04-25 08:57:36

标签: javascript php json

To use some variables in a JS script, I simply set them in a wrapper with JSON, like so:

<?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. 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.

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?

5 个答案:

答案 0 :(得分:0)

That's what JSON is all about: it's the JavaScript Object Notation - a format that's being natively understood by 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:

$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. The response body will be a string and this needs to be converted into a JavaScript object by using parseJSON. That's just one example. Opening a JSON file in nodejs is another one.

In your example you literally embedded the json_encode output into some JavaScript source (defined by the <script>tags). That's why the JavaScript interpreter catches up the JSON-syntax and constructs a JavaScript object from it.

答案 1 :(得分:0)

When you do this:

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

you're generating JavaScript code with PHP. 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:

<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. The parser parsing the script tag contents parses it as code, not as JSON. But that's fine, because as long as it's used as a right-hand value (e.g., on the right-hand side of = or passed into a function, etc.), JSON is valid JavaScript.

答案 2 :(得分:0)

JSON was modeled after the syntax for JavaScript literals.

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.

In which cases, then, do you need 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. You need to convert the JSON into JavaScript objects explicitly then.

答案 3 :(得分:0)

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 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).

    You often use PHP to generate JavaScript code. 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 theCtrl+U short-cut).

  • JavaScript and JSON are different languages and could hardly have less capabilities in common. JavaScript is a programming language and JSON is a data format. The only relation is that JSON creator has the idea of basing his language in a (very limited) subset of the JavaScript syntax. 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!

    (Of course, nobody uses eval() any more and as JSON became popular everybody has written proper parsers anyway.)

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

<?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)

答案 4 :(得分:0)

简单回答:

您没有使用引号

这首先由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值(数组,对象,数字等)的字符串表示。