在封装自己的JSONP 服务之前,我们要先明白,什么是同源?为什么要跨越?
首先我们要明白,同源策略是浏览器的一种安全策略,所谓同源是指,域名、协议、端口完全相同。
为什么要跨越?在开始前简单介绍一下CDN(contentdelivery network),CDN简称内容分发网络,当我们完成一个项目的时候,真正的功能性代码不多,可是静态资源确占很大一部分,如样式,图片等等,这些静态如果都向你这个服务器要数据的话,服务器压力就很大,所以很多时候,我们把这些静态资源放到其他的资源服务器上(比如淘宝这样大公司提供的服务,它在全国各地都有资源服务器,)这样即减轻了压力,也提高的速度。因此src这种属性必须是可以跨越的。 因此我们可以利用这个特性,去封装自己的jsonp ,来向其他服务器要服务。
function (url,callback){
// 1. 要有一个script标签
var scriptElem = document.createElement('script');
// 2. 要访问的url每一次调用这个函数时,回调的函数名都是不一样的。
避免第一次访问的响应还会到达时,第二次响应以及发出,导致回调函数被覆盖掉了
var callbackName = '__callback__' ;
// 3. 创建回调函数,并给url添加&callback=[回调函数的名字]
window[callbackName] = function (data){
// 回调函数内部:
// 1. 获取数据,并把数据传给上层callback
callback(data);
// 通知AngularJS,我们更新了数据,你去刷新一下视图
$rootScope.$apply();
// 2. 删除掉script标签
document.body.removeChild(scriptElem);
};
// 4. script加src属性
// 我们的url应该传入什么样的格式?
// http://xx.xx.com/api?callback=JSONP_CALLBACK
// 也就是说JSONP_CALLBACK这个字符串就相当于是函数名的占位符
scriptElem.src = url.replace('JSONP_CALLBACK',callbackName);
// 5. 把script标签插入到文档上
document.body.appendChild(scriptElem);
}
按上面的步骤就可以实现跨越,你只要把该函数封装到你要用的js文件中。
直接可用可以复制下面这段代码:
//跨域js 接口
function pkjsonpFn = (url, callback){
var scriptElem = document.createElement('script');
var callbackName = '_pkcallback' + count++;
window[callbackName] = function(data) {
callback(data);
document.body.removeChild(scriptElem);
};
scriptElem.src = url.replace('JSONP_CALLBACK', callbackName);
document.body.appendChild(scriptElem);
};
封装原生的Ajax :
var createAjax = function () {
var xhr = null;
try {
xhr = new ActiveXObject("microsoft.xmlhttp");
} catch (e1) {
try {
xhr = new XMLHttpRequest();
} catch (e2) {
window.alert("您的浏览器不支持ajax,请更换!");
}
}
return xhr;
};
var ajax = function (conf) {
var type = conf.type;
var url = conf.url;
var data = conf.data;
var dataType = conf.dataType;
var success = conf.success;
if (type == null) {
type = "get";
}
if (dataType == null) {
dataType = "text";
}
var xhr = createAjax();
xhr.open(type, url, true);
if (type == "GET" || type == "get") {
xhr.send(null);
} else if (type == "POST" || type == "post") {
xhr.setRequestHeader("content-type",
"application/x-www-form-urlencoded");
xhr.send(data);
}
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
if (dataType == "text" || dataType == "TEXT") {
if (success != null) {
success(xhr.responseText);
}
} else if (dataType == "xml" || dataType == "XML") {
if (success != null) {
success(xhr.responseXML);
}
} else if (dataType == "json" || dataType == "JSON") {
if (success != null) {
success(eval("(" + xhr.responseText + ")"));
}
}
} else if (xhr.readyState == 4 && xhr.status != 200) {
//alert("请求失败!");
}
};
};