JS实现简单的JSONP请求
- 思路
在dom中添加一个script脚本,url拼写到src属性中,其中一个关键的参数是callback,它是接收jsonp成功之后的回调。等请求成功之后,把回调函数释放。另外demo中添加了超时机制,详见demo如下:
var jsonpSeq = 0;
function jsonp(req) {
var callbackName = 'jsonpcb' + (++jsonpSeq);
//定义一个处理Jsonp返回数据的回调函数
window[callbackName] = function (object) {
console.log('callback...')
release('success');
req.success(JSON.parse(object));
}
var script = document.createElement("script");
//组合请求URL
script.src = req.url + "?callback=" + callbackName;
for (key in req.data) {
script.src += "&" + key + "=" + encodeURIComponent(req.data[key]);
}
console.log('src=' + script.src)
script.async = true;
//设置错误回调
script.onerror = function () {
release('error');
req.fail('error');
}
//设置超时时间
var timeout = req.timeout || 15000;
var timeoutid = setTimeout(function () {
release('timeout');
req.fail('timeout');
}, timeout);
//释放资源
function release(msg) {
console.log('release=' + msg)
//清除定时器
if (timeoutid) {
clearTimeout(timeoutid);
}
//清除节点中的脚本
if (script.parentNode) {
script.parentNode.removeChild(script);
}
//清除回调
if (msg === 'timeout') {
window[callbackName] = function () {
window[callbackName] = undefined;
try {
delete window[callbackName];
} catch (e) {
}
};
} else {
window[callbackName] = undefined;
try {
delete window[callbackName];
} catch (e) {
}
}
}
//将创建的新节点添加到BOM树上
document.getElementsByTagName("body")[0].appendChild(script);
}
- demo调用案例:
以360的jsonp接口为例,调用如下:
jsonp({
url: "https://sug.so.360.cn/suggest",
data: {
word: "js",
},
success: function (obj) {
console.log('jsonp success:' + JSON.stringify(obj))
},
fail: function (msg) {
console.log('jsonp fail:' + msg)
},
timeout: 10000
});
注意: 如果url请求的服务端端接口不支持jsonp,则无法实现。