springboot 3.2+vue,后端如何设置origins = *去解决跨域

由来

今天新开项目,用的之前的管理框架,springboot3.2+jdk17+vue2+elementui+axios,的时候,因为端口换了报错Access to XMLHttpRequest at ‘http://192.168.3.19:11111/user/info?personId=1’ from origin ‘http://192.168.3.19:22222’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: The value of the ‘Access-Control-Allow-Origin’ header in the response must not be the wildcard ‘*’ when the request’s credentials mode is ‘include’. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute

分析

从报错信息来看是最常见的跨域问题,跨域的定义是请求发起网站的协议://ip:端口号,有一个地方和请求地址不一致,就会引起跨域,但是我后端是配置了跨域,代码如下

    /**
     * CORS配置源, 解决跨域
     *
     * @return {@link CorsConfigurationSource}
     */
    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();

        // 允许所有头部
        corsConfiguration.setAllowedHeaders(List.of("*"));

        // 允许所有方法
        corsConfiguration.setAllowedMethods(List.of("*"));

        corsConfiguration.setAllowedOrigins(List.of("*"));

        // 设置预检请求的最大有效时间(秒)
        corsConfiguration.setMaxAge(CORS_MAX_AGE);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", corsConfiguration);
        return source;
    }

可以看到我设置了AllowedOrigins为*,按道理来说是可以允许所有请求访问的,但是为什么会报错呢?

原因

在查询了其他博客后,发现是前端axios配置的问题,代码如下

const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API,
  withCredentials: true, // send cookies when cross-domain requests
  timeout: 5000, // request timeout
});

首先我们都知道,请求都是无状态的,在前期的单体应用中,要知道请求的页面是否登录,只能通过请求携带sessionId去查看服务端session中是否有登录信息,但是现在引入了中间件redis等,可以通过在heard中携带token去判断请求是否登录了,
在这代码中,前端为了让后端识别请求是否登录,会携带sessionId,通过设置withCredentials: true去让服务端返回sessionId并在后面的请求携带此sessionId, 但是现在都是使用springboot+redis+jwt 去解决登录状态的维持,所以前端的请求可以是无状态的。

解决

知道原因后就可以很简单的知道怎么去解决,将vue的axions的配置withCredentials: true设置为false就好了,如下

const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API,
  withCredentials: false, // send cookies when cross-domain requests
  timeout: 5000, // request timeout
});

后端代码不需要动

拓展

当你需要后端返回sessionId该怎么设置。
也很简单,后端设置如下

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();

        // 允许所有头部
        corsConfiguration.setAllowedHeaders(List.of("*"));

        // 允许所有方法
        corsConfiguration.setAllowedMethods(List.of("*"));

        // 设置允许的源--搭配前端axios的withCredentials: true,
        corsConfiguration.setAllowedOrigins(List.of("http://localhost:22222", "http://192.168.3.19:22222"));

        // 明确允许凭据
        corsConfiguration.setAllowCredentials(true);

        // 设置预检请求的最大有效时间(秒)
        corsConfiguration.setMaxAge(CORS_MAX_AGE);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", corsConfiguration);
        return source;
    }

需要配置允许的请求头, corsConfiguration.setAllowedOrigins(List.of(“http://localhost:22222”, “http://192.168.3.19:22222”));和 corsConfiguration.setAllowCredentials(true);去告诉前端需要携带cookie去分辨你是否携带了sessionId
前端设置

const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API,
  withCredentials: true, // send cookies when cross-domain requests
  timeout: 5000, // request timeout
});

去携带初次访问返回的sessionId

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值