1.什么是跨域
同源策略
所谓同源是指域名、协议、端口均相同,若有任何一个不相同则需要通过跨域实现
跨域是指从一个域名的网页去请求另一个域名的资源,严格定义是:只要协议、域名、端口有任何一个不同,就被视作跨域
不能通过AJAX的open方法直接跨域请求
跨域方式:
- 跨域资源共享(CORS)
- 使用JSONP(常用)
- 修改document.domain
- 使用window.name
2.JSONP
JSONP是JSON with Padding(填充式json)的简写,是应用JSON的一种新方法,也是一种跨域解决方案(不是语言和数据格式)
JSONP由两部分组成:回调函数和数据,回调函数是当响应到来时应该在页面中调用的函数,数据就是传入回调函数中的JSON数据–JSON的接口只有对象和数组,JSONP的接口则由回调函数和数据组成
JSONP的原理:直接用XMLHttpRequest请求不同域上的数据是不可以的,但在页面上引入不同域上的js脚本文件却是可以的,JSONP正是利用这个特性来实现的(JSONP本身与AJAX没有关系)

利用标签的src或href属性跨域
function getJSONP(url,callback){
if(!url){//如果没有传入url则退出函数
return;
}
//JSONP的接口是在JSON数据外面包裹一个回调函数,如:abc([{user:1},{id:4}])
//括号内的JSON数据是服务器端传入的,而客户端需要将函数名称传给服务器,请求响应完成后服务器端返回的就是如上的例子
//函数名通过url地址传递,如:http://www.baidu.con?jsonp=abc 或 http://www.baidu.con?callback=abc,jsonp与callback并不是特定的,随便写都可以
//声明数组用来随机生成函数名
var a = ['a','b','c','d','e','f'],
r1 = Math.floor(Math.random()*a.length),//生成随机数并向下取整
r2 = Math.floor(Math.random()*a.length),
r3 = Math.floor(Math.random()*a.length),
name = 'getJSONP' + a[r1] + a[r2] + a[r3],//随机组成函数名
cbname = 'getJSONP.' + name;//向服务器传入cbname,服务器会传回getJSONP.ABC(...),ABC函数作为getJSONP函数的属性值存在,所以必须加getJSONP.的前缀
//处理url地址,先判定是否有问号,没有就加问号,有就加和号
if(url.indexOf('?') === -1){
url += '?jsonp=' + cbname;
}else{
url += '&jsonp=' + cbname;
}
//动态创建script标签
var script = document.createElement('script');
script.setAttribute('src',url);
document.getElementsByTagName('head')[0].appendChild(script);
//定义作为属性的函数
getJSONP[name] = function(data){//data用于接收服务器传回的数据
//为避免报错,尽量不用if判断是否执行成功
try{
callback && callback(data)//callback存在则执行
} catch(e){
//暂时不执行
} finally{
//执行完后删除该函数及创建的script标签
delete getJSONP[name];//delete只能删除函数与对象实例的属性和方法,不能删除变量和定义在原型链中的属性
script.parentNode.removeChild(script);//先找到父节点,然后删除script节点
}
}
}
getJSONP('http://class.imooc.com/api/jsonp',function(data){
console.log(data);
});
//JSONP本身不是真正的AJAX请求,只是利用了script标签的src属性

1030

被折叠的 条评论
为什么被折叠?



