为什么会出现跨域问题

同源策略

同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

什么是跨域

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

非同源限制

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

跨域问题解决

CORS

跨域资源共享(Cross-Origin Resource Sharing, CORS)是一种解决跨域请求的方案,其机制是使用一组额外响应头(Access-Control-Allow-Origin)和预检请求(OPTIONS)来使浏览器有权使用非同源资源。

需要注意

我可以在网关层或者单个服务解决跨域问题,但是别重复解决,否则会出现重复配置问题。

Access to XMLHttpRequest at ‘https://xxx.com/category/list?orgId=1’ from origin 
‘http://localhost:8080’ has been blocked by CORS policy: The ‘Access-Control-Allow-Origin’ header 
contains multiple values ‘*, *’, but only one is allowed.
spring、spring boot 解决跨域问题

跨域问题的解决,无非是在响应给浏览器的时候,在请求头中告诉浏览器我允许跨域。
我们可以在过滤器、拦截器中,在响应的请求头中增加对跨域的支持。

public class CorsInterceptor extends HandlerInterceptorAdapter {
	@Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {
        // 允许跨域                      
		response.addHeader("Access-Control-Allow-Origin", "*");
		// 允许前端携带cookie:启用此项后,上面的域名不能为'*',必须指定具体的域名
        // response.addHeader("Access-Control-Allow-Credentials", "true");
        // 允许跨域的方法
        response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT,PATCH, HEAD");
        // 允许跨域的头
        response.addHeader("Access-Control-Allow-Headers", "Content-Type, X-Requested-With");
        // 跨域的有效期,在有效期内,无需检查跨域问题
        response.addHeader("Access-Control-Max-Age", "3600");

		// 该字段可选。CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。
		// response.addHeader("Access-Control-Expose-Headers", "XXX");
		
        return super.preHandle(request, response, handler);
    }        
}

cookie怎么跨域传递

前后端都需要进行处理
前端:

var xhr = new XMLHttpRequest(); 
xhr.withCredentials = true

后端:

response.setHeader("Access-Control-Allow-Credentials", "true"); 

Referrer Policy

referer参数是http请求头header里的一个关键参数,表示的意思是链接的来源地址,比如在页面引入图片、JS 等资源,或者跳转链接

no-referrer
整个 Referer 首部会被移除。访问来源信息不随着请求一起发送

no-referrer-when-downgrade (默认值)
在没有指定任何策略的情况下用户代理的默认行为。在同等安全级别的情况下,引用页面的地址会被发送(HTTPS->HTTPS),但是在降级的情况下不会被发送 (HTTPS->HTTP)。

origin
在任何情况下,仅发送文件的源作为引用地址。例如 https://example.com/page.html 会将 https://example.com/ 作为引用地址。

origin-when-cross-origin
对于同源的请求,会发送完整的URL作为引用地址,但是对于非同源请求仅发送文件的源。

same-origin
对于同源的请求会发送引用地址,但是对于非同源请求则不发送引用地址信息

strict-origin
在同等安全级别的情况下,发送文件的源作为引用地址(HTTPS->HTTPS),但是在降级的情况下不会发送 (HTTPS->HTTP)。

strict-origin-when-cross-origin
对于同源的请求,会发送完整的URL作为引用地址;在同等安全级别的情况下,发送文件的源作为引用地址(HTTPS->HTTPS);在降级的情况下不发送此首部 (HTTPS->HTTP)。

unsafe-url
无论是同源请求还是非同源请求,都发送完整的 URL(移除参数信息之后)作为引用地址。(最不安全的策略了)

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐