跨域 以及解决办法

214 阅读4分钟

一、出现有跨域的原因:

浏览器的同源策略限制。

二、什么是跨域:

当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域

三、非同源限制

  1. 无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB
  2. 无法接触非同源网页的 DOM
  3. 无法向非同源地址发送 AJAX 请求

四、跨域解决方法

1、设置document.domain解决无法读取非同源网页的 Cookie问题:

比如在两个子域名:aaa.xxx.com bbb.xxx.com aaa里的一个网页(a.html)引入了bbb 里的一个网页(b.html), 这时a.html里同样是不能操作b.html里面的内容的。 需要在a.html里与b.html里都加入:document.domain = "xxx.com"; 前提条件:这两个域名必须属于同一个基础域名!而且所用的协议,端口都要一致,否则无法利用document.domain进行跨域

2、跨文档通信 API:window.postMessage():

调用postMessage方法实现父窗口 向子窗口发消息(子窗口同样可以通过该方法发送消息给父窗口); 它可用于解决以下方面的问题:

  1. 页面和其打开的新窗口的数据传递;
  2. 多窗口之间消息传递;
  3. 页面与嵌套的iframe消息传递;
  4. 上面三个场景的跨域数据传递 代码如下:

040f4e58711274c71b0db4e19bfb0516.jpg

3、JSONP

JSONP 是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,兼容性好(兼容低版本IE),缺点是只支持get请求,不支持post请求。 核心思想:前端发起请求时指定回调函数,向服务器请求 JSON 数据,服务器收到请求后,将数据放在约定好名字的回调函数的参数位置传回来。

前端示例:

image.png

后端示例:

image.png 【4】CORS CORS 是跨域资源分享(Cross-Origin Resource Sharing)的缩写。它是 W3C 标准,属于跨源 AJAX 请求的根本解决方法。 浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。 只要同时满足以下两大条件,就属于简单请求。 a09fa20694015ac2492c59e956ac6ce6.jpg 普通跨域请求:只需服务器端设置Access-Control-Allow-Origin2、带cookie跨域请求:前后端都需要进行设置 【前端设置】根据xhr.withCredentials字段判断是否带有cookie【服务端设置】

前端示例:

baaf82101cfd369592b46c57160e8321.jpg 服务器端对于CORS的支持,主要是通过设置Access-Control-Allow-Origin来进行的。如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问。 Java为例:

f63dc0f24bfa218b84e68a7f74b08aa5.jpg

【5】webpack 本地代理

在webpack.config.js中利用webpackDevServer 配置本地代理 devServer

f5e04680bedfc6408f2e8ecab9efb336.jpg 配置简单示例如下:

88a25f8d73013c503526fb9dbab3210a.jpg

【6】websocketWebsocket

websocketWebsocket是 HTML5 的一个持久化的协议,它实现了浏览器与服务器的全双工通信,同时也是跨域的一种解决方案。WebSocket 和 HTTP 都是应用层协议,都基于 TCP 协议。但是 WebSocket 是一种双向通信协议,在建立连接之后,WebSocket 的 服务器与 客户端都能主动向对方发送或接收数据。同时,WebSocket 在建立连接时需要借助 HTTP 协议,连接建立好了之后 client 与 server 之间的双向通信就与 HTTP 无关了。

【7】Nginx反向代理

Nginx 实现原理类似于 Node 中间件代理,需要你搭建一个中转 nginx 服务器,用于转发请求。 使用 nginx 反向代理实现跨域,是最简单的跨域方式。只需要修改 nginx 的配置即可解决跨域问题,支持所有浏览器,支持 session,不需要修改任何代码,并且不会影响服务器性能。

我们只需要配置nginx,在一个服务器上配置多个前缀来转发http/https请求到多个真实的服务器即可。这样,这个服务器上所有url都是相同的域 名、协议和端口。因此,对于浏览器来说,这些url都是同源的,没有跨域限制。而实际上,这些url实际上由物理服务器提供服务。这些服务器内的 javascript可以跨域调用所有这些服务器上的url。 nginx 目录下的 nginx.conf 配置的简单示例如下

44acefe1e6228a52d409ee6461702d8d.jpg

当用户请求www.test.com/en/docs/ 会被loaction匹配到 然后到将www.test.com/en/docs/ 代理到nginx.org,