发送 JSONP 请求
使用 <script>
元素可以进行 Ajax 传输的原因如下:
- 不受同源策略的影响
- 包含 JSON 编码数据的响应会自动解析
这种使用 <script>
元素作为 Ajax 传输的技术叫做 JSONP。
假设你已经写了一个服务,它处理 GET 请求并返回 JSON 编码的数据,同源的文档可以通过 XMLHttpRequest 对象和 JSON.parse()
,如果服务器上启用了 CORS,在较新的浏览器上,跨域的文档也可以使用 XMLHttpRequest 享受该服务,在不支持 CORS 的旧版本浏览器中,跨域的文档只能通过 JSONP 访问这个服务。
当通过 <script>
元素调用数据时,响应内容必须用 JavaScript 函数名和圆括号包裹起来。为了可行起见,我们必须告诉以某种方式告诉后端服务,它正在从一个<script>
元素调用,必须返回一个 JSONP 响应,这可以通过在 URL 中添加一个查询参数来实现。
在实践中,支持 JSONP 的服务不会强制指定客户端必须实现的回调函数名称,而是使用查询参数的值,允许客户端指定一个函数名,然后使用该函数名去填充响应:
function getJSONP(url, callback) {
// 为本次请求创建一个唯一的回调函数名称
var cbnum = "cb" + getJSONP.counter++;
var cbname = "getJSONP." + cbnum;
// 将回调函数名称以表单编码的形式添加到URL的查询部分
// 使用jsonp作为参数名(另一些常见的实现使用callback作为参数名)
if (url.indexOf("?") === -1) {
url += "?jsonp=" + cbname;
} else {
url += "&jsonp=" + cbname;
}
// 创建 script 元素用于发送请求
var script = document.createElement("script");
// 调用将被脚本执行的回调函数
getJSONP[cbnum] = function (response) {
try {
callback(response);
} finally {
delete getJSONP[cbnum];
script.parentNode.removeChild(script);
}
};
// 立即触发 HTTP 请求
script.src = url;
document.body.appendChild(script);
}
getJSONP.counter = 0;
无评论