JavaScript/处理 JSON
外观
处理 JSON 可能需要添加一个支持库,它创建全局 JSON 对象。此对象仅在新浏览器(例如 FF 3.5、IE8)中才原生存在。可以在 此处 找到此类库。
//Parsing JSON:
var myObject = JSON.parse(myJSONtext)
//Creating JSON:
var myJSONText = JSON.stringify(myObject);
在旧浏览器中,您可以使用以下语法,但这会引发安全问题,例如 XSS。
var myObject = eval("(" + myJSONtext + ")")
鉴于浏览器对 跨域 Ajax 的限制(在某些早期浏览器中仅通过配置允许,在 IE8 中通过非标准方式允许,并在 HTML5 中通过服务器标头允许),绕过这些限制的一种方法(同时仍然需要一些服务器端脚本协调)是让网站动态地在他们的代码中插入一个 HTML 脚本标签,从而他们目标的跨域脚本(通常)提供 JSON,但包装在函数调用中(函数名称根据请求者提供的“回调”参数的值来提供)或其他可执行代码。
在 PHP 中,您可以像这样简单地提供 JSONP
<?php
if (isset($_GET['callback'])) {
header('Content-Type: application/javascript');
$our_site_data = ... // Set to an array or object containing data to be supplied for use at other sites
print $_GET['callback'] . '(' . json_encode($our_site_data) . ')';
}
?>
jQuery 和其他框架有自己的生成 JSONP 请求的方法,但我们将使用以下自定义代码。
注意:重要的是要记住,如果目标站点或目标站点提供的数据可能来自不可信来源,则不应使用以下代码,因为此类脚本可能以使用站点的权限(例如,读取用户 cookie 并将它们传递到另一个站点)运行,从而执行 跨站点脚本 攻击。
<script>
var JSONP = function(global) { // Introduces only one global
// MIT Style license, adapted from http://devpro.it/code/209.html
function JSONP(uri, callback) {
function JSONPResponse() {
// Reduce memory by deleting callbacks when finished
try { delete JSONP[src] } catch(e) { JSONP[src] = null; }
documentElement.removeChild(script);
// Execute the user's callback with the arguments supplied by the server's JSONP call
if (typeof callback === 'string') { // Assumes only one return argument and that it is an HTML string
document.getElementById(callback).innerHTML = arguments[0];
} else {
callback.apply(this, arguments);
}
}
// Ensure a unique callback
var src = '_' + id++,
script = document.createElement("script");
// Add our callback as a property of this JSONP
// function to avoid introducing more globals
JSONP[src] = JSONPResponse;
// We include "callback", as it is typically used in
// JSONP (e.g., on Wikibooks' API) to specify the callback
documentElement.insertBefore(
script,
documentElement.lastChild
).src = uri + (uri.indexOf('?') === -1 ? '?' : '&') + "callback=JSONP." + src;
}
var id = 0, documentElement = document.documentElement;
return JSONP;
}(this);
// Get the parsed HTML of this page you are reading now
// using the Mediawiki API (See https://wikibooks.cn/w/api.php
// for Wikibooks, but it also applies at other Mediawiki wikis) that
// allows for such cross-domain calls
JSONP('https://wikibooks.cn/w/api.php?action=parse&format=json&page=JavaScript/Handling_JSON',
function (data) {
alert(data.parse.text['*']);
}
);
</script>