您的位置 首页 java

浏览器跨域根因分析及解决方案

根因分析

造成跨域的根本原因是,两个资源的协议、域名、子域名、端口不同,而且是只要有一个不同,这种情况下所进行的访问行动都是跨域的。而出于安全性的考虑,浏览器通常会限制跨域访问,不允许跨域请求资源,这是浏览器的同源策略。但是需要非常明确一点的是,跨域请求被禁止,并不是浏览器拦截了跨域请求,导致请求发不出去,而是请求发到了服务端,在服务端的过滤器 filter 中进行了校验逻辑,本质就是根据Request Headers中Origin属性的值,与服务器端的 CORS Configuration配置中允许的源进行比较,如果Request Headers中Origin属性的值存在于服务器允许的源的列表中,则请求允许通过,继续往下请求,否则请求被拦截,返回403错误。

注意:网上看到很多说是请求到了服务端,服务端也返回了请求处理的结果,只是浏览器把结果拦截了的说法,我认为是不正确的,因为请求根本没有到我们要调用的方法中,就已经被过滤器拦截了。

解决方案

跨域资源共享(Cross Origin Resource Share)是一种允许一个网页上的JavaScript向另一个域中发出 AJAX 请求机制 。CORS机制的工作原理通过添加一些特定的HTTP头部标识,使得浏览器被告知下载的资源应当被允许给定的域(或者所有的域)进行Web请求。

可以对如下的ResponseHeaders参数进行设置,以达到跨域资源请求。

Access-Control-Allow-Origin :指定授权域来进行跨域请求,如果此项没有限制,使用*作为参数值。

Access-Control-Allow-Credentials :指定跨域请求是否需要验证。

Access-Control-Expose-Headers :指示哪一种头部标识可以被安全的暴露(公开)。

Access-Control-Max-Age :指定预检请求的最大缓存时间。

Access-Control-Allow-Methods :指定进行跨域请求时使用的方法。

Access-Control-Allow-Headers :指定实际的请求过程中哪些头部标识可以使用。

代码示例

浏览器跨域根因分析及解决方案

有两种方式都可以解决这个跨域报错问题:

  1. 第一种如上自定义一个CorsFilter,在代码中自定义CorsConfiguration。
  2. 在controller层面添加@CrossOrigin注解即可,添加这个注解后框架会自动帮我们默认生成一个配置类CorsConfiguration,如下图:
浏览器跨域根因分析及解决方案

框架自动生成的CorsConfiguration

浏览器三模块参数说明

在浏览器的一个常规请求中,通常包含三部分 General ,Response Headers,Request Headers。

#请求服务器路径

Request URL:

#请求方法Get

Request Method: GET

#请求响应码

Status Code: 200

#服务器IP+ 端口号

Remote Address: 10.0.245.245:443

#访问来源策略

Referrer Policy: no-referrer-when-downgrade

Response Headers

#证书验证

access-control-allow-credentials: true

#允许访问的源

access-control-allow-origin:

#采用gzip压缩,压缩效果最好

content-encoding: gzip

content-type: application/json;charset=UTF-8

#返回时间

date: Thu, 02 Jul 2020 02:07:19 GMT

#返回状态码

status: 200

strict-transport-security: max-age=15724800; includeSubDomains

vary: Accept-Encoding, Origin, Access-Control-Request-Method, Access-Control-Request-Headers

x-svc: cs-backend-test-rbs-service-http

Request Headers

#指定客户端能够接收的内容类型

Accept: application/json, text/plain, */*

#授权值,服务器根据这个值解析出token

Authorization: Bearer ae7a11114-193f-4122-a615-d465807f615c

#源

Origin:

#访问来源

Referer:

#post请求下会存在这个值,指明消息主体数据的编码方式,也就是传到后台参数数据的编码方式

Content-Type: application/json;charset=UTF-8

#安全获取模式

Sec-Fetch-Mode: cors

#token值

token: ae7a11114-193f-4122-a615-d465807f615c

#浏览器信息

User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.36 Safari/537.36

总结

1.两个资源的协议、域名、子域名、端口不同,这种情况下所进行的访问行动都是跨域的。而出于安全性的考虑,浏览器通常会限制跨域访问,不允许跨域请求资源。

2.跨域只存在于浏览器端,是受到了浏览器的同源策略的限制。

3.CORS,跨域资源共享(Cross Origin Resource Share)是一种允许一个网页上的JavaScript向另一个域中发出AJAX请求机制。

4.跨域请求被禁止,并不是浏览器拦截了跨域请求,导致请求发不出去,而是请求发到了服务端,在服务端的过滤器filter中进行了校验逻辑,本质就是根据Request Headers中Origin属性的值,与服务器端的CorsConfiguration配置中允许的源进行比较,如果Request Headers中Origin属性的值存在于服务器允许的源的列表中,则请求允许通过,继续往下请求,否则请求被拦截,返回403错误。

5.之所以会跨域,是因为受到了同源策略的限制,同源策略要求源相同才能正常进行通信,即协议、域名、端口号都完全一致。

文章来源:智云一二三科技

文章标题:浏览器跨域根因分析及解决方案

文章地址:https://www.zhihuclub.com/181859.shtml

关于作者: 智云科技

热门文章

网站地图