一,什么是跨域
跨域,或者称为跨源资源共享(CORS),是Web开发中经常遇到的一个概念。它涉及到浏览器安全策略和不同源之间的资源共享问题。当一个Web页面(源A)尝试去请求另一个不同源的Web资源(源B)时,由于浏览器的同源策略限制,这种请求通常会被阻止,这就是跨域。
二,跨域的产生
跨域问题产生的原因主要是浏览器的同源策略(Same Origin Policy)限制。同源策略是一种安全机制,它要求页面请求的接口地址必须与页面的url地址处于同域上,即域名、端口和协议必须相同。这是为了防止某个域名下的接口被其他域名下的网页非法调用,从而保护用户数据的安全。
然而,在实际应用中,为了减轻web服务器的负载,我们常常将js、css、图片等静态资源分离到另一台独立域名的服务器上,并通过相应的标签从不同域名下加载这些静态资源。这种情况下,虽然浏览器允许这些静态资源的跨域加载,但对于其他方式(如Ajax)发起的请求,浏览器仍然会限制脚本中发起的跨域请求。因此,当Web应用程序尝试通过XMLHttpRequest对象或Fetch API向不同域名的资源发起HTTP请求时,就会遇到跨域问题。
三,进行跨域
CORS(跨域资源共享)
CORS是一种W3C规范,它定义了一种浏览器和服务器交互的方式来确定是否允许跨源请求。CORS利用HTTP头部信息来告知浏览器哪些源是允许访问的。
1. 简单请求
如果请求满足以下所有条件,则被视为简单请求:
请求方法是以下之一:HEAD, GET, POST
HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type(但需要注意,其值仅限于text/plain, multipart/form-data, application/x-www-form-urlencoded)
对于简单请求,浏览器会先发送一个预检请求(preflight request),预检请求是一个OPTIONS请求,用于询问服务器是否允许实际的跨域请求。如果服务器同意,那么浏览器才会发送实际的跨域请求。
2. 预检请求
预检请求会包含一些额外的HTTP头部信息,如Origin和Access-Control-Request-Method,用于告诉服务器请求的来源和请求方法。服务器可以通过检查这些头部信息来决定是否允许该跨域请求。
3. 响应头部
如果服务器同意跨域请求,它需要在响应头部中包含一些CORS相关的字段,如Access-Control-Allow-Origin、Access-Control-Allow-Methods和Access-Control-Allow-Headers等,来告诉浏览器哪些源、哪些方法和哪些头部信息是允许访问的。
Java 简单实现跨域
@CrossOrigin注解来开启CORS支持
package com.zwxict.user.controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author 汤义
* @create 2024-02-15:45
*/
@RestController
@RequestMapping("/api")
@CrossOrigin(origins = "http://yitang.com")
public class TestController {
````
}
其中@CrossOrigin中的2个参数:
origins: 允许可访问的域列表
maxAge:准备响应前的缓存持续的最大时间(以秒为单位)。
配置全局跨域访问解决方案
package com.zwxict.common.config;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author 汤义
* @create 2024-02-16:31
*/
public class MyWebConfig{
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
//添加映射路径
registry.addMapping("/yitang/**")
//放行哪些原始域
.allowedOrigins("*")
//是否发送Cookie信息
.allowCredentials(true)
//放行哪些原始域(请求方式)
.allowedMethods("GET","POST", "PUT", "DELETE")
//放行哪些原始域(头部信息)
.allowedHeaders("*")
//暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)
.exposedHeaders("Header1", "Header2");
}
};
}
}
以上是两种处理跨域问题,还有大概三种处理方式jsonnp,响应头添加Header,配置nginx反向代理,zuul组件,这里就不过多的讲解了。