原理
- HTML 标签中存在某些标签可进行跨域资源的下载,如:img, script, link
- 当通过 script 标签的 src 属性引用外部代码文件时,浏览器默认通过 GET 请求进行下载,并自动将其内容作为 JS 代码执行
- 通过 JS 动态创建 script 元素,设置 src 属性为请求的 URL,且拼接 callback 回调参数,将 script 元素插入 document 文档中,浏览器进行 http 请求
- 服务端收到请求后,返回 callback 函数执行的 JS 代码,并将返回的数据作为参数传给 callback 函数
- 需将 callback 回调方法挂到 window 全局,script 标签中的代码可以直接调用全局的变量和函数
实现过程
以下为使用原生 JS 实现的过程,实际开发中可使用一些经过封装的第三方库更为方便简洁,如 jQuery 中的 ajax 方法
- 动态创建 script 元素并插入到文档中
// 为了防止多次请求 callback 名重复一般加上一个随机数
var callback = 'abc' + Math.floor(Math.random() * 100000);
var url = `http://www.xxx.com/path?callback=${callback}¶m=123`;
var script = document.createElement('script');
script.src = url;
document.head.appendChild(script);
- 将 callback 回调挂到 window 全局中
window[callback] = function(data) {
// data 为请求返回的数据
// {status: "ok", msg: "Hello, world!"}
console.log(data);
}
// 浏览器 http 请求返回示例:
// abc24190({"status":"ok","msg":"Hello, world!"})
- 请求完成后移除相关 script 元素
document.head.removeChild(script);
delete window[callback];
后记:JSONP 需要服务端进行处理支持