如果有遗漏,评论区告诉我进行补充
面试官: 你对跨域了解多少?
我回答:
跨域问题,即Cross-Origin Resource Sharing(CORS),是现代Web开发中一个非常重要的概念,涉及到浏览器的安全策略——同源策略(Same-origin policy)。下面我将详细介绍跨域的概念、原因、影响以及解决方法。
一、跨域的概念
跨域是指从一个域名的网页去请求另一个域名的资源时,浏览器出于安全考虑,会限制一些请求。具体来说,如果请求的URL的协议、域名、端口三者中任意一个与当前页面的URL不同,则被认为是跨域请求。
例如,http://example.com:8080
和 https://example.com:8080
被认为是不同的源。
二、跨域问题的背景
跨域问题的本质是浏览器的同源策略(Same-Origin Policy)限制。同源策略是浏览器最核心也最基本的安全功能,用于保证用户信息的安全,防止恶意网站读取另一个网站的数据。
三、跨域问题的常见表现
- 无法读取非同源网页的Cookie、LocalStorage和IndexedDB。
- 无法接触非同源网页的DOM。
- 无法向非同源地址发送AJAX请求。
四、Java后端解决跨域问题的方式
在Java后端,尤其是在使用Spring Boot等框架时,解决跨域问题主要有以下几种方式:
-
使用@CrossOrigin注解
- 注解在方法上:允许特定方法跨域。
- 注解在类上:允许整个类的所有方法跨域。
- origins属性:指定允许跨域的源地址,可以使用“*”表示允许所有源。
- 注意:@CrossOrigin注解只适用于Spring MVC的Controller层。
-
通过配置文件实现全局跨域
- 实现WebMvcConfigurer接口,并重写addCorsMappings方法。
- 在该方法中,通过CorsRegistry注册跨域映射,设置允许跨域的路径、源地址、HTTP方法等。
-
自定义CorsFilter
- 创建一个CorsFilter的Bean,并在其中配置跨域信息。
- 这种方式相对灵活,但需要更多的代码量。
-
手动设置响应头
- 在Controller的方法中,通过HttpServletResponse对象手动设置响应头,如Access-Control-Allow-Origin等。
- 这种方式较为原始,不推荐用于全局跨域配置。
-
使用Nginx反向代理
- 当后端服务无法直接修改响应头时,可以在Nginx中配置反向代理,通过Nginx设置跨域相关的响应头。
- 这种方式适用于前后端分离的场景,且Nginx作为静态资源服务器或反向代理服务器。
- 在自己的服务器上设置一个代理,转发请求到目标服务器,这样请求就变成了同源请求。
-
WebSocket
- WebSocket协议本身不受同源策略的限制,可以用来绕过跨域问题。
-
PostMessage API
- 允许两个不同源的窗口之间进行通信,但实现较为复杂。
-
JSONP(JSON with Padding)
- 一种古老的解决方法,利用
<script>
标签没有跨域限制的特性,但仅限于GET请求,并且有安全风险。
- 一种古老的解决方法,利用
五、CORS通信原理
CORS(Cross-Origin Resource Sharing)是一种基于HTTP的协议,它允许服务器明确表示哪些源站可以通过网页来访问其资源。CORS通过添加额外的HTTP头信息来允许或拒绝跨域请求。
-
预检请求(Preflight Request):
如果请求方法不是GET、HEAD、POST,或者请求中包含了某些自定义的HTTP头部(如Content-Type
以外的头部),浏览器会先发送一个OPTIONS
方法的预检请求到目标服务器,询问服务器是否允许这样的跨域请求。 -
响应头:
服务器需要在响应中包含以下CORS相关的头部:Access-Control-Allow-Origin
:指定哪些源可以访问资源,可以是具体的域名或*
(允许所有源)。Access-Control-Allow-Methods
:列出允许的HTTP方法。Access-Control-Allow-Headers
:列出允许的自定义请求头。Access-Control-Max-Age
:预检请求的有效期,单位是秒。
-
实际请求:
如果预检请求得到服务器的正面响应,浏览器才会发送实际的请求。
六、跨域与JSONP的比较
- JSONP:一种利用
<script>
标签不受同源策略限制的特性来实现跨域请求的方法。但JSONP只支持GET请求,且存在安全风险(如XSS攻击)。 - CORS:比JSONP更强大,支持所有类型的HTTP请求,且更安全。CORS是现代Web开发中解决跨域问题的首选方案。
七、总结
跨域问题是Web开发中常见的问题之一,理解其背后的原理和解决方法对于提升Web应用的安全性和兼容性至关重要。在Java后端开发中,通过合理的配置和使用框架提供的跨域解决方案,可以有效地解决跨域问题。