惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - Franky
有赞技术团队
有赞技术团队
宝玉的分享
宝玉的分享
雷峰网
雷峰网
Hugging Face - Blog
Hugging Face - Blog
V
V2EX
大猫的无限游戏
大猫的无限游戏
博客园 - 司徒正美
D
Docker
T
The Blog of Author Tim Ferriss
罗磊的独立博客
博客园 - 叶小钗
酷 壳 – CoolShell
酷 壳 – CoolShell
Blog — PlanetScale
Blog — PlanetScale
月光博客
月光博客
J
Java Code Geeks
Jina AI
Jina AI
博客园 - 【当耐特】
C
Check Point Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
腾讯CDC
Last Week in AI
Last Week in AI
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
V
Visual Studio Blog

沐凉`Blog

沐凉·日记 沐凉·日记 沐凉·日记 Flutter开发Linux程序中文乱码解决 | 沐凉`Blog Docker安装Nginx | 沐凉`Blog 沐凉·日记 flutter loading 动画插件(flutter_spinkit 4.1.2) | 沐凉`Blog 沐凉·日记 Linux 常用指令、IntelliJ IDEA 常用快捷键 | 沐凉`Blog 了解23种设计模式-单例模式 | 沐凉`Blog Spring Boot 邮件服务提供者 | 沐凉`Blog Docker 搭建redis单节点以及一主两从三哨兵模式 | 沐凉`Blog 沐凉·日记 Hello World | 沐凉`Blog Ubuntu Server 安装 Java、Tomcat、mysql | 沐凉`Blog
关于使用@CrossOrigin遇见的的一些问题和理解 | 沐凉`Blog
2019-12-05 · via 沐凉`Blog

记录今天遇到的一个问题

个人理解 参考需谨慎。如果有错误,谢大佬指点

是关于跨域的,在昨天写项目的时候遇到的跨域请求的问题,网上通常的配置方法都是使用 过滤器,或者 实现 WebMvcConfigurer 接口的方法。相对来说有些老了。不符合我想要的效果。

1
2
3
4
5
6
7
8
9
10
11
12
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
.allowCredentials(true)
.maxAge(3600)
.allowedHeaders("*");
}
}

然后我在阅读 Spring 官网 看到有使用 @CrossOrigin 方式可以只需要加一个注解就行(简单粗暴我喜欢)。于是我便采用的这种方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@RestController
@CrossOrigin(value = "*",allowCredentials = "true")
@RequestMapping("user")
public class UserController {
@PostMapping(value = "login")
public Map<String, Object> login(@RequestBody User user) {
Map<String, Object> map = new HashMap<>();
map.put("userName",user.getUserName());
map.put("userPass",user.getUserPass());
return map;
}
@PostMapping(value = "logout")
public Map logout(@RequestBody String token) {
Map<String, String> map = new HashMap<>();
map.put("token",token);
return map;
}
}

配置之后问题就来了在访问 login 接口的时候可以正常访问,但是 请求 logout接口的时候,还是出现的跨域的问题。

在反复检查配置,阅读官网后。尝试了上面的方法配置,完全没问题 (那我代码应该没问题 2333),但是换回 @CrossOrigin 依旧请求失败。

由于那种配置方法比较死,不是很灵活 (我不喜欢)。所以我想继续使用 @CrossOrigin 的方式配置。

于是便把部分代码抽取出来,单独建一个干净的项目复现刚才的问题。

按照 Spring 官网的配置方法一路通畅。于是对比这个 demo 和我原先的 项目,便发现了原因 !!!

因为我配置了一个登录拦截器,用于验证 token 。拦截器不拦截 login 方法。拦截需要验证 token 的方法,所以就出现了部分有效,部分无效的问题。
所有经过了拦截器的方法都无法访问。

好,知道了问题的所在,让我继续翻文档。。。。

了解到。@CrossOrigin 这个注解本质也是一个拦截器,往response里添加 Access-Control-Allow-Origin 等响应头信息。
如果在 controller 类上或在方法上标了 @CrossOrigin 注解,则 spring 在记录 mapping 映射时会记录对应跨域请求映射。

当一个跨域请求过来时,spring 在获取 handler 时会判断这个请求是否是一个跨域请求,如果是,则会返回一个可以处理跨域的 handler

QAQ 这时候找到 HandlerMapping 里的 getCorsHandlerExecutionChain方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
protected HandlerExecutionChain getCorsHandlerExecutionChain(HttpServletRequest request,
HandlerExecutionChain chain, @Nullable CorsConfiguration config) {

if (CorsUtils.isPreFlightRequest(request)) {
HandlerInterceptor[] interceptors = chain.getInterceptors();
chain = new HandlerExecutionChain(new PreFlightHandler(config), interceptors);
}
else {

chain.addInterceptor(0, new CorsInterceptor(config));
}
return chain;
}

找到 CorsInterceptorpreHandle打上断电点,和自己的拦截器打上断点(自己的先执行,凉凉)

好像 Spring 也没给配置拦截器执行顺序的东东(菜鸡的我不知道)

到此可以知道,@CrossOrigin 是在 spring 映射 handler 的时候 干的活。那既然拦截器不行,那我就用 Spring AOP 吧 QWQ !!!
或者在拦截器中设置,只要是预请求(OPTIONS)全部直接放行