##JSONP的理解
说来惭愧,以前只知道用jsonp跨域,src和iframe能跨域,原生jsonp是怎么实现的呢,我却木有思考过
到了邮件这边以后,遇到了不能用第三方库用原生写跨域的需求,研究了一下jsonp
现在才知道,jsonp实际上是先声明一个回调函数,利用
<script>
标签的src来跨域请求返回一段js代码执行,而这个执行的代码是要放在这个事先声明的函数里的
因为有时不能和后台固定死一个回调函数名,所以在window下注册一个全局变量来接受函数名就可以实现动态定义回调函数了
以下是代码实现
/**
* 获取js脚本
* @method getScript
* @param {string}_url 请求url
* @param {function}_callback 回调函数
* @return {void}
*/
_getScript: function(_url, _charset, _callback, _error) {
// 异步加载解决
setTimeout(function() {
var READY_STATE_RE = /loaded|complete|undefined/;
var script = document.createElement("script");
script.setAttribute("charset", _charset || "utf-8");
script.setAttribute("type", "text/javascript");
script.setAttribute("src", _url);
script.async = "async";
var callback = function(_status) {
if (READY_STATE_RE.test(script.readyState)) {
script.onload = script.onerror = script.onreadystatechange = null;
script.parentNode.removeChild(script);
script = undefined;
//IE10下新加载的script会在此之后执行,所以此处需延迟执行
// 成功
if (_status) {
if (typeof _callback == "function") {
setTimeout(_callback, 0);
}
} else {
// 有error的时候使用error
if (typeof _error == "function") {
setTimeout(_error, 0);
} else if (typeof _callback == "function") {
setTimeout(_callback, 0);
}
}
}
};
script.onload = function() {
callback(true);
};
script.onerror = function() {
callback(false);
};
script.onreadystatechange = function() {
callback(true);
};
var head = document.getElementsByTagName("head")[0];
head.appendChild(script);
}, 0);
}
/**
* 模拟jsonp
* @deprecated 已经废弃,一般使用跨域ajax调用
*/
jsonp: function(_url, _callback, _settings) {
var settings = $.extend({
charset: "utf-8"
}, _settings);
var funcName = "_tmp_jsonp_callback" + (+new Date);
if (settings.funcName) {
funcName = settings.funcName;
}
window[funcName] = function() {
_callback && _callback.apply(window, arguments);
try {
delete window[funcName];
} catch (e) {}
}
var callbackObj = {};
callbackObj[(settings.callbackName || "callback")] = funcName;
// _settings里面加入自定义callbackname,for文件中心里面不是用callback作为回调函数名。
var url = this.appendURL(_url, callbackObj);
this.getScript(url, settings.charset, function() {
// _callback && _callback.apply(window,arguments);
try {
window[funcName]();
// 删除临时变量
delete window[funcName];
} catch (e) {}
});
}