跨域

151 阅读6分钟

第一部分

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

2、同源: 当一个请求url的协议、域名、端口三者之间都与当前页面的url相同,即请求的资源和当前HTML资源在同一服务器上并且端口号、请求的方式一致。即便两个不同的域名指向同一个ip地址,也非同源。

如下表可见:

1076231-20211111142903368-2113198822.png

3、解决跨域方法:

解决办法:

1、 通过jsonp跨域
2、 document.domain + iframe跨域
3、 location.hash + iframe
4、 window.name + iframe跨域
5、 postMessage跨域
6、 跨域资源共享(CORS)
7、 nginx代理跨域
8、 nodejs中间件代理跨域
9、 WebSocket协议跨域
10、cors服务器设置访问的白名单
11、jsonp利用html的有点标签或者属性不受同源策略的限制

4、 JSONP:

JSONP 是 JSON with padding(填充式 JSON 或参数式 JSON)的简写。JSONP 是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,兼容性好(兼容低版本IE),缺点是只支持get请求,不支持post请求

后端实现:

const Koa = require("koa");
const fs = require("fs");
const app = new Koa();

app.use(async (ctx, next) => {
  if (ctx.path === "/api/jsonp") {
    const { cb, msg } = ctx.query;
    ctx.body = `${cb}(${JSON.stringify({ msg })})`;
    return;
  }
});

app.listen(8080);

JSONP的原理: 通常为了减轻web服务器的负载,我们把js、css,img等静态资源分离到另一台独立域名的服务器上,在html页面中再通过相应的标签从不同域名下加载静态资源,而这是被浏览器允许,基于此原理我们可以通过动态创建script,再请求一个带参网址实现跨域通信即利用<script>的src 不受同源策略约束来跨域获取数据。

** JSONP 由两部分组成**:回调函数数据。回调函数是当响应到来时应该在页面中调用的函数。回调函数的名字一般是在请求中指定的。而数据就是传入回调函数中的 JSON 数据。

如动态创建

设置src,回调函数在src中设置:

1076231-20171203101713413-712973414.png

**  在页面中,返回的JSON作为参数传入回调函数中,我们通过回调函数来来操作数据。**

function handleResponse(response){
//对esponse数据进行操作代码
}

1076231-20211111163538159-1816128709.png

5、Node正向代理:

代理的思路为,利用服务端请求不会跨域的特性,让接口和当前站点同城。

[代理前] image-20200412202320482

[代理后] image-20200412202358759

6、跨域-CoRS:

原理:

向响应头header中注入Access-Control-Allow-Origin,这样浏览器检测到header中的Access-Control-Allow-Origin,则就可以跨域操作了。CORS跨域分为简单请求和复杂请求。

跨域造成的CSRF攻击解决方案:

防止CSRF攻击,浏览器的Cookie新增加了一个SameSite属性

sameSite有三个值:

strict、Lax(设置前两个,基本杜绝了CSRF的攻击)、none

strict:最严格,完全禁止第三方Cookie,跨站时,任何情况都不会发送Cookie,只有当前网页的URL与请求目标一直,才会才上Cookie

Lax:大多数情况不发送第三方Cookie,但是导航到目标网址的Get请求除外。

None:关闭sameSite属性,将其设置为None,必须同时设置Secure属性(cookie只能通过 https协议发送),否则无效。

简单请求: 在头信息中加origin字段
服务器返回:Access-Control-Allow-Origin

复杂请求:

发送预检请求,使用OPTION请求,用于询问要被跨域访问的服务器是否允许当前域名下的页面发送跨域的请求

  • 发送OPTION请求(携带以下请求头)
  • origin\
  • Access-Control-Request-Header\
  • Access-Control-Request-Methods\
  • 服务器收到请求后,检查origin、Access-Control-Request-Header、Access-Control-Request-Methods,确认允许跨域做出回应:
  • Access-Control-Allow-Origin\
  • Access-Control-Allow-Methods\
  • Access-Control-Allow-Headers\
  • 然后发起第二次正常请求\
  • origin\
  • 服务器返回:\
  • Access-Control-Allow-Origin

发生预检请求的条件:

  • 1.请求方法不是GET、POST、HEAD其中任意一个\
  • 2.不是下面定义对CORS安全的首部字段(请求头信息)集合,而是是集合之外的其他首部字段。\
  • Accept、Accept-Language、Content-Language、Content-Type、DPR、Downlink、Save-Data、Viewport-Width、Width。\
  • 3.Content-Type的值不是text/plain、multipart/form-data、application/x-www-form-urlencoded中任意一个值\
  • ps:content-type常用四个取值:text/xml、multipart/form-data、application/x-www-form-urlencoded、application/json

相对字段作用:

请求头:
origin :发起跨域请求的源域名
Access-Control-Request-Header :用于在预检请求时,告知服务器要发起的跨域请求中会携带的请求头信息
Access-Control-Request-Methods :用于表明跨域请求使用的HTTP方法\

响应头:
Access-Control-Allow-Origin:携带服务器验证后允许的跨域请求的域名。
Access-Control-Allow-Methods :用于告知浏览器实际发送跨域请求时,可以支持的请求方法
Access-Control-Allow-Headers :用于告知浏览器实际发送跨域请求时,可以支持的请求头
Access-Control-Allow-Credentials:表示是否允许发送Cookie
Access-Control-Max-Age:用来指定本次预检请求的有效期
Access-Control-Expose-Headers:用于允许返回给跨域请求的响应头列表,在列表中的响应头的内容,才可以被浏览器访问。

第二部分:

一:跨域请求:

1、jsonp

利用了 script 不受同源策略的限制

缺点:只能 get 方式,易受到 XSS攻击

2、CORS(Cross-Origin Resource Sharing),跨域资源共享

当使用XMLHttpRequest发送请求时,如果浏览器发现违反了同源策略就会自动加上一个请求头 origin;

后端在接受到请求后确定响应后会在 Response Headers 中加入一个属性 Access-Control-Allow-Origin;

浏览器判断响应中的 Access-Control-Allow-Origin 值是否和当前的地址相同,匹配成功后才继续响应处理,否则报错

缺点:忽略 cookie,浏览器版本有一定要求

3、方式分为两种请求:

一种是简单请求,另一种是非简单请求

简单请求跨域:

请求方式为HEAD、POST 或者 GET

非简单请求跨域:

非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json

二、常见跨域场景:

当协议、子域名、主域名、端口号中任意一个不相同时,都算作不同域。不同域之间相互请求资源,就算作“跨域”。常见跨域场景如下图所示:

三、同源策略限制内容有:

url的组成

  • Cookie、LocalStorage、IndexedDB 等存储性内容
  • DOM 节点
  • AJAX 请求发送后,结果被浏览器拦截了

但是有三个标签是允许跨域加载资源:

  • <img src=XXX>
  • <link href=XXX>
  • <script src=XXX>

第三部分:为什么需要跨域?

1.限制不同源的请求

这里还是用最常用的方式来讲解,例如用户登录 a 网站,同时新开 tab 打开了 b 网站,如果不限制同源, b 可以像 a 网站发起任何请求,会让不法分子有机可趁。

2.限制 dom 操作

我举个例子吧, 你先登录下 www.baidu.com ,然后访问我这个网址。