CORS通信过程,都是浏览器或http插件自动完成,不需要 用户/开发人员 参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码是完全一样的。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求(预检译请求),但用户不会有感觉。
所以:实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
一、请求的不同
浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。
只要同时满足以下两大条件,就属于简单请求。
(1) 请求方法是以下三种方法之一:
- HEAD
- GET
- POST
(2)HTTP的头信息不超出以下几种字段:
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type:只限于三个值
application/x-www-form-urlencoded
、multipart/form-data
、text/plain
这是为了兼容表单(form),因为历史上表单一直可以发出跨域请求。AJAX 的跨域设计就是,只要表单可以发,AJAX 就可以直接发。
凡是不同时满足上面两个条件,就属于非简单请求。
浏览器对这两种请求的处理,是不一样的。
二、服务端需要的支持
当进行跨域资源访问时,使用了上面的非简单请求👆(HTTP的头信息中出现了以上枚举以外的字段或请求方式复杂)需要服务端进行配置,在springboot项目中可以这样设置:
- java版本
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
public void addResourceHandlers(@NotNull ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
}
public void configureViewResolvers(@NotNull ViewResolverRegistry registry) {
super.configureViewResolvers(registry);
}
public void addInterceptors(@NotNull InterceptorRegistry registry) {
}
// 这里设置跨域资源访问
public void addCorsMappings(@NotNull CorsRegistry registry) {
Intrinsics.checkParameterIsNotNull(registry, "registry");
// 设置headers中可以添加任何信息访问/api/v1下的所有接口
registry.addMapping("/api/v1/**").allowedOrigins(new String[]{"*"});
}
public void configureMessageConverters(@NotNull List converters) {
super.configureMessageConverters(converters);
}
}
- kotlin版本
@Configuration
@EnableWebMvc
class WebConfig : WebMvcConfigurer{
override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
super.configureViewResolvers(registry)
}
override fun addInterceptors(registry: InterceptorRegistry) {
}
// 这里设置跨域资源访问
override fun addCorsMappings(registry: CorsRegistry) {
// 设置headers中可以添加任何信息访问/api/v1下的所有接口
registry.addMapping("/api/v1/**").allowedOrigins("*")
}
override fun configureMessageConverters(converters: MutableList<HttpMessageConverter<*>>) {
super.configureMessageConverters(converters)
}
}
2022-03-14续