前端网络——跨域
一、什么是跨域
1、跨域是指浏览器不能执行其他网站脚本,它是由浏览器同源策略造成的,是js的安全机制。
2、我们知道,页面本身由协议、域名、端口号等组成,例如:https://www.baidu.com:80。只要协议、域名和端口号三者中有任意一个不同,就算跨域。
跨域发生在哪里?
跨域行为发生在浏览器。
=过程=
在一次请求数据的过程中:
即使发生了跨域,请求亦可以发出;
服务器端可以接收、正常处理并正常返回;
数据返回后,浏览器可以接受到数据;
接收数据后,浏览器发现当前页面的域同请求的域不同,判定为跨域。
代码在等待结果,但是浏览器判定跨域,不会把结果传给代码。
=结束=
虽然发生了跨域,但是确实需要所请求的数据,怎么办呢?
二、解决跨域问题
(一)后端配合进行跨域
1、JSONP方法(本次只使用这个方法解决)
2、后端设置Access-Control-Allow-Origin属性以支持跨域
(二)后端不配合进行跨域
1、iframe方式(但只能显示、不能控制)
2、通过自己的后端代理
三、代码
1、原生js发送ajax
<script>
var oDiv=document.getElementById('test');
var xhr=null;//创建一个http请求的对象
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();//常用浏览器带的
}else{
xhr=new ActiveXObject("Microsoft.XMLHTTP");//支持IE6
}
xhr.open("get","url");
xhr.onreadystatechange=function(){
//status==200 网络请求,结果都会有一个状态码,来表示这个请求是否正常,2××标识成功,3××标识重定向,4××表示客户端错误,5××表示服务端错误
if(xhr.readyState==4&&xhr.status==200){//状态4表示请求已完成,已接收到数据
oDiv.innerText=xhr.responseText;//接受到的数据保存在responseText
var data=JSON.parse(xhr.responseText);
console.log(data);
}
}
xhr.send();
</script>
2、JSONP跨域
1、使用方法:
<script>
//jsonp格式哪里特殊?
//发送的时候,会带上一个参数callback
//返回的结果不是json
//callback的名+(+json+);
$.ajax({
url:"http://developer.duyiedu.com/edu/testJsonp",
type:"get",//请求类型
dataType:"jsonp",//数据类型
success:function(data){
console.log(data);
}
});
</script>
2、JSONP原理
script标签身上的src属性是不受同源策略限制的,特征是需要后端配合。script标签有src属性,可以发出跨域请求。虽然可以使用其他域上的资源,但是浏览器会将返回内容作为js代码执行。如果有一个与callback值相同的函数看,则会调用这个函数,打印出其中的内容。
1、判断请求与当前页面的域是否同源,如果同源则发送正常的ajax,不跨域。
2、如果不同源,则生成一个script标签
3、生成一个随机的callback名字,创建一个名为这个的方法。
4、设置script标签src,设置为要请求的接口
5、将callback作为参数拼接在后面
6、后端收到请求后开始准备要返回的数据
7、后端拼接数据,将要返回的数据用callback的值包裹起来
8、返回内容
9、浏览器接收到内容,当作js代码执行
10、执行名为这个的方法,从而获取到了要请求的数据。
<script>
//jsonp原理
//场景:从一个接口获取一个数据,跨域、接口支持jsonp
//script标签,有src属性可以发出跨域请求。虽然可以使用其他域的资源,但是浏览器会将返回的内容作为js代码执行。
var $={
ajax:function(options){
var url=options.url;
var type=options.type;
var dataType=options.dataType;
//判断是否同源:协议、域名、端口号
//获取目标的url的域
var targetprotocol="";//目标接口的协议
var targetHost="";//目标接口的host,host是包含域名和端口的
//如果url不带http,那么访问的一定是相对路径,相对路径一定是同源的。
if(url.indexOf("http://")==0||url.indexOf("https://")==0){
var targetUrl=new URL(url);
targetprotocol=targetUrl.protocol;
targetHost=targetUrl.host;
}else{
targetprotocol=location.protocol;
targetHost=location.host;
}
//首先判断是否为jsonp,不是jsonp不用做其他判断,直接发送ajax
if(dataType=='jsonp'){
//看是否同源
if(location.protocol==targetprotocol&&location.host==targetHost){
//此处省略,因为同源,jsonp会当作普通的ajax请求
// }
}else{//不同源
//随机生成一个callback;
var callback="cb"+Math.floor(Math.random()*1000000);
//给window添加callback方法。
console.log(callback);
window[callback]=options.success;
//生成script标签
var script=document.createElement('script');
if(url.indexOf("?")>0){//表示有参数了
script.src=url+"&callback="+callback;
}else{
script.src=url+"?callback="+callback;
}
script.id=callback;
document.head.appendChild(script);
}
}
}
}
$.ajax({
url:"http://developer.duyiedu.com/edu/testJsonp",
type:'get',
dataType:'jsonp',
success:function(data){
console.log(data);
}
});
</script>
本次就写到这里,各位朋友,多学习,多总结哦!欢迎批评指正,谢谢。