文章目录
github源码
跨域是什么?
协议、域名、端口有一个不一致就会导致跨域问题
跨域发送的请求会被浏览器处理吗?
跨域请求浏览器可以正常发送服务器也可以正常返回响应,只不过响应被浏览器拦截了而已。如果请求是有返回值的,会被浏览器隐藏掉。
关于几种跨域的方式的优缺点分析
1.CORS
简单请求
简单请求:
- 浏览器会直接发送AJAX请求,并在HTTP头部添加一个Origin字段,表示请求的来源。
- 如果服务器接受跨域请求,将在HTTP头部返回一个Access-Control-Allow-Origin字段,表示允许此来源的请求。
- 如果服务器不允许跨域请求,将返回一个403 Forbidden错误。
GET
POST
HEAD
- 请求头Accept
- 请求头Accept-Language
- Content-Language
Content-Type
的值仅限于下列三者之一:text/plain
multipart/form-data
application/x-www-form-urlencoded
复杂请求
复杂请求:
- 先发送一个预检请求OPTION,在HTTP头部添加了一个Access-Control-Request-Method字段,表示实际的请求方法,以及可能存在的Access-Control-Request-Headers字段,表示实际的请求头。
- 服务器需要在HTTP头部返回一个Access-Control-Allow-Methods字段,表示允许的请求方法,以及一个Access-Control-Allow-Headers字段,表示允许的请求头。
- 如果服务器不允许跨域请求,将返回一个403 Forbidden错误。
PUT
COntent-type
不属于以上三种
戳这里看MDN详解
前端满足复杂请求的条件,后端作一定的配置处理,具体可以查看下图
如果设置access-control-allow-origin: *
会有什么问题吗?
*不允许携带认证头和cookies
2.document.domain
该方式只能用于二级域名相同的情况下,比如 http://a.test.com 和 http://b.test.com 适用于该方式。
只需要给页面添加 document.domain =‘test.com’ 表示二级域名都相同就可以实现跨域。
a.html
b.html
3.jsonp
由于浏览器的
<script> | <src> | <ifream>
标签没有跨域限制,网页可以得到从其他来源动态产生的 JSON 数据。JSONP请求一定需要对方的服务器做支持才可以.
优点:简单兼容性好,可用于解决主流浏览器的跨域数据访问的问题。
缺点:是仅支持get方法具有局限性,不安全可能会遭受XSS攻击。
function jsonp(req) {
var script = document.createElement('script');
var url = req.url + '?callback=' + req.callback.name;
script.src = url;
document.getElementsByTagName('head')[0].appendChild(script);
}
4.nginx
实现原理类似于Node中间件代理,需要你搭建一个中转nginx服务器,用于转发请求。
使用nginx反向代理实现跨域,是最简单的跨域方式。只需要修改nginx的配置即可解决跨域问题,支持所有浏览器,支持session,不需要修改任何代码,并且不会影响服务器性能。
5.postMessage
允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。
- 页面和其打开的新窗口的数据传递
- 多窗口之间消息传递
- 页面与嵌套的iframe消息传递
- 上面三个场景的跨域数据传递
6.websocket
Websocket是HTML5的一个持久化的协议,它实现了浏览器与服务器的全双工通信,同时也是跨域的一种解决方案。WebSocket和HTTP都是应用层协议,都基于 TCP 协议。但是 WebSocket 是一种双向通信协议,在建立连接之后,WebSocket 的 server 与 client 都能主动向对方发送或接收数据。同时,WebSocket 在建立连接时需要借助 HTTP 协议,连接建立好了之后 client 与 server 之间的双向通信就与 HTTP 无关了。
a.html
server.js
7.window.name+ifream
其中a.html和b.html是同域的,都是
http://localhost:3000
;而c.html是http://localhost:4000