我可以将json_encode的结果直接插入到JavaScript代码中吗?或者我必须使用JSON,parse?

5vf7fwbs  于 2023-05-02  发布在  Java
关注(0)|答案(2)|浏览(178)

我正在做一些广泛的测试,以了解如何PHP和JS变量,对象,数组等可以成功地传递给另一个。在这个问题上有许多令人困惑的问题/答案。
根据我的测试,我可以创建各种PHP对象:

$testarray = ["this", "is", "me"];
$testobject = (object) array("this"=>"that", "is"=>"was", "me"=>"him");
$teststring = "this is me";
$testnum = 9758.25;

然后我可以通过json_encode()传递它们(仍然是PHP)

echo '<script>
    var testarray = '.json_encode($testarray).';
    var testobject = '.json_encode($testobject).';
    var teststring = '.json_encode($teststring).';
    var testnum = '.json_encode($testnum).';
</script>';

并且当运行时,这导致:

<script>
    var testarray = ["this","is","me"];
    var testobject = {"this":"that","is":"was","me":"him"};
    var teststring = "this is me";
    var testnum = 9758.25;
</script>

我只是想确认这个结果是,并且永远是,完全有效的JavaScript?我看不出它有什么问题,但有些来源推荐使用JSON.parse()。在这种情况下是否需要这样做?
我知道如果JS中的数组或对象通过JSON.stringify()传递,我必须解析它。
我还知道,要将对象或数组从JS发送到PHP,我必须使用JSON.stringify()json_decode()使它们有效,但似乎json_encode()导致有效的JS而不必使用JSON.parse()

1aaf6o9v

1aaf6o9v1#

是的,它是有效的,因为JSON语法是JavaScript对象文字语法的子集。因此,如果您以所示的方式将JSON编码的文本注入到生成的JS代码中,那么它的行为就像一个对象文字,就像您手工编写的一样。
JSON.parse将是必需的,如果您正在接收一个包含JSON编码文本的字符串到JavaScript变量中(例如:例如,作为 AJAX 请求的结果),并且需要将其从字符串转换为可用的对象。

5uzkadbs

5uzkadbs2#

你可能认为直接插值就足够了。但有一个棘手的案子__proto__.

var obj0 = {"__proto__": {"a": 5}};
var obj1 = JSON.parse('{"__proto__": {"a": 5}}');

console.log(obj0.a);
console.log(Object.getPrototypeOf(obj0) === Object.prototype);

console.log(obj1.a);
console.log(Object.getPrototypeOf(obj1) === Object.prototype);

在对象文字中,需要"__proto__":键来设置正在构造的对象的原型,除非它被写成["__proto__"]:;在解析JSON时将抑制此规则。这在ECMA-262第13版中规定。,§13.2.5.5,第4种变体。
如果你的JSON对象总是固定的类结构,你可能永远不会遇到这个问题,但是如果你曾经使用JSON对象来表示任意的键值Map,这对你来说可能是一个讨厌的惊喜。
因此,将JSON序列化到JavaScript源代码中的真正安全的方法是将字符串编码两次为字符串字面量,并在JS端解析该字面量:

var testarray = JSON.parse(<?=json_encode(json_encode($testarray)); ?>);

令人惊讶的是,这种技术也可以用于some performance benefits。JavaScript语法足够复杂,实际上可以将对象字面量的解析推迟到运行时,以便能够使用更简单和更高性能的JSON解析器。但与往常一样,性能可能会因引擎、版本和数据量而异,而且很难保证。首先考虑正确性,其次考虑性能。

相关问题