后端通过CorsRegistry配置了全局跨域,但是前端仍然报CORS跨域错误

  • 问题背景

    在实现登录功能时,我先是通过CorsRegistry配置了全局跨域,然后配置了一个登录拦截器后前端就报错CORS跨域错误

  • 问题原因

    • 前置知识

      首先我们来了解一下什么是跨域错误,跨域错误(Cross-Origin Error)是在Web开发中常见的错误之一,它发生在浏览器执行跨源请求(从一个源访问另一个源)时。同源策略(Same-Origin Policy)是浏览器的安全机制,它限制了通过脚本在不同源之间进行跨域通信。”源”是由协议、主机名和端口号组成的标识符。如果两个页面的协议、主机名和端口号完全相同,则它们被视为同源。同源策略的存在是为了保障网站安全、防止跨站脚本攻击。

    • 原因分析

      在前后端分离的项目中,很容易出现跨域错误,因为前端和后端的端口号、主机名一般都不相同,此时前端能够发送请求给后端,但是由于同源策略的存在,会直接被浏览器给拦截。从而出现CORS错误。

      浏览器如何判断当前是否跨域呢?浏览器会在发送真实请求之前先发送一个OPTIONS请求,这个请求相当于一个探子,如果发现目标路径可达并且端口、主机一致就会直接通过,如果不一致浏览器就会直接拦截前端的请求,导致后续的真实请求(比如GET、POST、PUT、DELETE)无法发送到后端。

      所以错误的跟本原因在于OPTIONS,由于我配置了登录拦截器,对于放行请求,不会有什么问题,但是对于没有放行的请求,会直接拦截OPTIONS请求,OPTIONS请求是一个探测请求,内部并不会携带token,所以就直接导致OTIONS请求被拦截,这样就会让浏览器觉得请求不可达,直接在前端报CORS error

  • 问题解决

    解决跨域问题的方法有很多,我了解的有配置代理(配置代理的方式也有很多,比如Nginx、大部分前端脚手架也有自带的Prox模块用于配置代理)、使用JSONP的 标签也可以配置跨域,我一般都是直接在后端配置跨域的,可以使用**CorsRegistry对象进行全局配置,也可以使用@CrossOrigin注解**进行单个请求配置,而当前项目中我所使用的是 CorsRegistry 对象进行全局配置。

    • 方案一:直接使用代理,比如Nginx、前端脚手架自带的代理(可行,但我没有使用)

    • 方案二:在后端的登录拦截器中放行所有的OPTIONS请求(采用并成功解决

可以看到配置后,重启后端项目,然后就没有出现 CORS error错误了

参考文章

  • SpringBoot加了拦截器后出现的跨域问题解析