跨域问题
什么是跨域?
跨域(Cross-Origin Issue)的存在是因为浏览器的安全限制,它防止恶意网站利用跨域请求来获取用户的敏感信息或执行恶意操作。浏览器通过实施同源策略来限制网页在不同源之间进行资源访问或交互的情况。当一个网页的协议、域名、或端口与当前页面的协议、域名、或端口不一致时,就会发生跨域问题。
跨域问题通常涉及以下情况:
- 跨域AJAX请求:当通过XMLHttpRequest或Fetch API发送AJAX请求时,如果请求的目标URL与当前页面的协议、域名或端口不一致,就会被认为是跨域请求。
- 跨域资源共享(CORS)问题:在AJAX请求中,如果目标服务器没有正确配置跨域资源共享的响应头部信息,则浏览器会阻止通过AJAX获取跨域资源。
- 跨域脚本攻击(XSS)问题:当一个网页加载了恶意脚本并在其他网页的上下文中执行时,就会发生跨域脚本攻击。
什么是浏览器的同源策略?
浏览器的同源策略(Same-Origin Policy)是一种安全机制,用于限制在浏览器中加载的网页从获取其他来源的资源或与其他来源的网页进行交互。它是为了防止恶意网站进行跨站点脚本攻击(Cross-Site Scripting,XSS)、跨站请求伪造(Cross-Site Request Forgery,CSRF)等安全威胁而设计的。
同源策略要求请求必须满足以下三个条件才能被认为是同源:
- 协议相同:两个页面的协议必须相同(例如,都是http://或都是https://)。
- 域名相同:两个页面的域名必须相同(例如,www.example.com 和 example.com 被视为不同域名)。
- 端口相同:如果指定了端口号,那么两个页面的端口号必须相同。
当发生跨域请求时,浏览器会阻止以下操作:
- 跨域的 AJAX 请求(XMLHttpRequest 或 Fetch API)。
- 跨域的 Cookie、LocalStorage 或 IndexDB 存储访问。
- 跨域的 DOM 操作,例如获取其他域下的元素或修改其样式。
- 跨域的嵌入 iframe 元素之间的交互。
例如,如果一个网页在 http://example.com
的环境下运行,那么它只能与 http://example.com
或者 https://example.com
相同的协议、域名和端口的资源进行交互。如果尝试访问不同源的资源,浏览器会阻止这些操作。
如何解决跨域问题?
解决跨域问题有多种方法,可以根据具体的场景选择适合的解决方案,常用方法如下:
-
JSONP(JSON with Padding):JSONP 利用
<script>
标签没有跨域限制的特点,在目标网页中通过动态创建<script>
标签来加载跨域的 JavaScript 文件,并在 URL 参数中传递回调函数的名称,使得目标网页将数据作为函数参数传递给回调函数。JSONP 只适用于 GET 请求。 -
CORS
(Cross-Origin Resource Sharing):CORS 是一种在服务端设置响应头部信息的机制,允许特定的源进行跨域访问。通过在目标服务器的响应中设置合适的 CORS 头部,如Access-Control-Allow-Origin
,Access-Control-Allow-Methods
,Access-Control-Allow-Headers
等,可以控制允许的跨域访问行为。 -
代理服务器:通过在自己的服务器上设置一个代理接口,将跨域请求发送到目标服务器,再将获取到的结果返回给前端。前端只需要与自己的服务器进行通信,避免了直接与目标服务器跨域通信的问题。
-
WebSocket:WebSocket 协议本身不受同源策略限制,可以在浏览器和服务器之间建立持久连接,实现实时双向通信。使用 WebSocket 可以规避跨域问题。
-
postMessage API:如果页面之间需要进行跨域通信,可以使用 postMessage API,在不同窗口或 iframe 间传递消息。这种方法适用于不同窗口、不同域的页面之间的通信需求。
SpringBoot 解决跨域问题
注:环境中出现跨域问题的原因有很多,解决方法并不相同,根据具体的场景选择适合的解决方案即可。
方式一:@CrossOrigin 注解
在 SpringBoot 中,在 Controller 类上使用 @CrossOrigin
注解解决跨域问题:
@CrossOrigin
@RestController
public class LoginController {@PostMapping("/login")public User login(@RequestBody User user){return user;}}
方式二:CorsConfig.java 配置类(常用)
在项目中创建一个名为 CorsConfig.java
配置类来启用 CORS 支持,解决跨域问题:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class CorsConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**") // 允许所有URL.allowedOrigins("*") // 设置允许跨域请求的源,这里设置为允许所有源.allowedMethods("GET", "POST", "PUT", "DELETE") // 允许的请求方法.allowedHeaders("*") // 允许的请求头.allowCredentials(true) // 允许携带认证信息(如cookies).maxAge(3600); // 预检请求的缓存时间(单位:秒)}
}