同源策略(跨域的原因)
- 端口相同
- 域名相同
- 协议相同
同源策略的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据
同源策略的限制范围
- Cookie、localStorage 和IndexDB无法读取
- DOM无法获得
- AJAX 请求不能发送
跨域通信的方式
- JSONP
- CORS
- Hash
- postMessage
- WebSoket
- 代理
JSONP跨域
浏览器虽然有同源策略限制,但是像cript标签、link标签、img标签、iframe标签,这种在标签上通过src地址来加载一些内容的时候浏览器是允许进行跨域请求的,所以JSONP的原理就是
- 创建一个script标签,这个script标签的src就是请求的地址
- 这个script标签插入到DOM中,浏览器就根据src地址访问服务器资源
- 返回的资源是一个文本,但是因为是在script标签中,浏览器就会执行它
- 而这个文本恰好是函数调用的形式,即函数名(数据),浏览器会把它当做JS代码来执行即调用这个函数
- 只要提前约定好这个函数名,并且这个函数存在于window对象中,就可以把数据传递给处理函数
CORS跨域
CORS(Cross-origin resource sharing) 跨域资源请求
浏览器在请求一个跨域资源的时候,如果是跨域的Ajax请求,它会在请求头中添加提个origin
,但是他不知道这个资源服务器是否允许跨域请求,浏览器会发送到服务端,如果服务器返回的头中没有'Access-Control-Allow-Origin:对应网址或 * '的话,那么浏览器就会把请求内容给忽略掉,并且在控制台报错
CORS限制
允许请求的方法
- GET
- POST
- HEAD
允许请求的Content-Type
- text/plain
- mutipart/form-data
- application/x-www-form-ulencoded
其他类型的请求方法和Content-Type需要通过预请求验证后才能发送
Hash值跨域通信
背景:在页面A下提供iframe或frame嵌入了跨域的页面B
容器页面 -> 嵌入页通信:
在A页面中改变B的url中的hash值,B不会刷新,但是B可以通过window.onhashchange时间监听到hash变化
postMessage通信
// 窗口A
window.postMessage('data','http://a.com')
// 窗口B
window.addEventListener('message',function(event){
console.log(event.origin) // http://a.com
console.log(event.source) // A对象的window引用
console.log(event.data) // 数据
})
WebSocket 跨域通信
var ws = new WebSocket('wss://echo.websoket.org') // 后端接口
ws.onopen = function(e){
ws.send('hello')
}
ws.onmessage = function(e){
console.log(e.data)
}
ws.onclose = function(e){
console.log('连接关闭')
}
代理
可以通过nginx代理、node Server进行请求转发