聊一聊JS的跨域
1.什么是跨域?
聊到跨域就不得不先聊一下浏览器的同源策略,为什么这么说呢,因为正是由于浏览器的同源策略才出现的跨域。同源策略,它是Netscape
提出的一个著名的安全策略。所谓同源是指,域名,协议,端口相同。当一个浏览器的两个tab页中分别打开两个不同的页面,在发送请求的
时候服务器首先会检查是否同源,如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。因此出现跨域的情况
主要有以下几种:
(1)网络协议不同,如http协议、https协议。
(2)端口不同,如8080 、8089等端口。
(3)域名不同,如baidu.com、JD.com。
(4)子域名不同,如java.aaa.com、js.aaa.com。
(5)域名和域名对应ip,如www.aaa.com访问20.205.28.90.
2.常用的解决跨域请求资源的方法有如下几种:
(1)jsonp
定义和用法:通过动态的插入一个script标签,由于浏览器对script的资源引用没有同源限制,所以利用 script标签,加载src路径,实现跨域加载js文
件。该js文件中需要定义好一个方法,将该方法名传递给服务端,服务端根据该方法名,拼装一个方法调用语句,响应给浏览器。浏览器来执行该语句调用
方法,通过参数,将响应的数据取出即可。
缺点:只能使用get请求,不支持post请求。
使用的是script标签,存在安全隐患。
获取的数据格式一般为json格式。
实例:原生js方法
<script>
function onBack(data) {
console.log(data.name); // 获取返回的结果
}
</script>
<script>
var _script = document.createElement('script');
_script.type = "text/javascript";
_script.src = "http://localhost:8080/jsonp?callback=onBack";
document.head.appendChild(_script);
</script>
ajax方法:
$.ajax({
url:"./js/text.js",
type:"GET",
dataType:"jsonp",
jsonpCallback:"onBack",
success:function(data){
console.log(data)
},
error:function(res){
console.log("请求失败!")
}
})
(2)CORS 【Cross-Origin Resource Sharing】
定义和用法:是现代浏览器支持跨域资源请求的一种最常用的方式。
使用方法:一般需要后端人员在处理请求数据的时候,添加允许跨域的相关操作。如下:
res.writeHead(200, {
"Content-Type": "text/html; charset=UTF-8",
"Access-Control-Allow-Origin":'http://localhost',
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers': 'X-Requested-With, Content-Type'
}
(3)window.psotMessage
定义和用法:postMessage()方法允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。
使用方法:postMessage(data,origin),该方法接受两个参数,data是指要传递的数据参数,origin是字符串参数,用来表明指定的目标源,包括协议+
主机+端口。
缺点:具有一定的兼容性
(4)document.domain跨子域
定义和用法:使用者前提是这两个域名必须属于同一个基础域名!而且所用的协议,端口都要一致,否则无法利用document.domain进行跨域,所以只能跨
子域
实现方法: 现在存在两个域名aaa.xxx.com和bbb.xxx.com。在aaa下嵌入bbb的页面,由于其document.name不一致,无法在aaa下操作bbb的js。可以在
aaa和bbb下通过js将document.name = 'xxx.com';设置一致,来达到互相访问的作用。
缺点:存在一定的限制,必须两个域名属于同一个基础域名。
(5)WebSocket
定义和用法:它是html5的一种api,可以在一个连接上提供全双工,双向通信。
实现方法:在JS创建了web socket之后,会有一个HTTP请求发送到浏览器以发起连接。取得服务器响应后,建立的连接会使用HTTP升级从HTTP协议交换为
web sockt协议。
缺点:仅限在支持web socket协议的服务器上工作。
var socket = new WebSockt('ws://www.baidu.com');
socket.send('hello WebSockt');
socket.onmessage = function(event){
var data = event.data;
}
(6)proxy代理
定义和用法:proxy将请求发送给后台服务器,通过服务器来发送请求,然后将请求的结果返回到前端。
使用方法:通过nginx代理