【已解决】记 Vue3+SpringBoot 前后端分离项目部署时的一次跨域问题

问题背景是在一次部署开发环境时,由于是前后端分离项目(前端Vue3,后端SpringBoot),SpringBoot 使用 Docker 部署,前端访问服务接口时出现跨域问题。

不知道什么是跨域问题的小伙伴可以查看另一篇文章:快速解决Spring Boot跨域困扰:使用CORS实现无缝跨域支持_I’m Jie的博客-CSDN博客

后端服务在现

创建一个最简单的 SpringBoot 项目,在 Controller 中添加一个返回 JSON 数据的接口用于后续前端项目访问,启动项目:

@RestController
public class LoginController {

    @PostMapping("/login")
    public User login(@RequestBody User user){
        return user;
    }

}

前端工程在现

使用 npm init vue@latest 命令创建一个 Vue3 工程,执行 npm install 命令安装依赖,之后使用 npm run dev 命令启动项目,访问 http://127.0.0.1:5173/:

【已解决】记 Vue3+SpringBoot 前后端分离项目部署时的一次跨域问题_第1张图片

执行 npm install axios 命令安装 Axios 用于访问后端服务的接口,并在 http.js 文件中添加 Axios 对应的配置:

import axios from 'axios'

// 创建axios实例
const http = axios.create({
  baseURL: 'http://127.0.0.1:8080',
  timeout: 5000
})

// axios请求拦截器
http.interceptors.request.use(config => {
  return config
}, e => Promise.reject(e))

// axios响应式拦截器
http.interceptors.response.use(res => res.data, e => {
  return Promise.reject(e)
})

export default http

在 testAPI.js 文件中封装对应的 API:

//封装测试接口函数
import http from '@/utils/http'

export const loginApi = ({ account, password }) => {
    return http({
        url: '/login',
        method: 'POST',
        data: {
            account:account,
             password:password
        }
    })
}

在 Vue 文件中进行调用:

import http from '@/utils/http'
import { onMounted } from 'vue';

//测试接口
onMounted(()=>{
  http.post('/login', {
    username: 'Fred',
    password: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

})

刷新页面,查看开发者工具,发现报跨域问题,原因是我们的前端工程使用的是 127.0.0.1 和 5173 端口,而后端服务使用的是8080端口,所以不可避免出现跨域问题:

【已解决】记 Vue3+SpringBoot 前后端分离项目部署时的一次跨域问题_第2张图片

Access to XMLHttpRequest at 'http://127.0.0.1:8080/login' from origin 'http://localhost' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

访问位于“”的XMLHttpRequesthttp://127.0.0.1:8080/login’来自原点’http://localhost’已被CORS策略阻止:对飞行前请求的响应未通过访问控制检查:请求的资源上不存在“access control Allow Origin”标头。

此时响应头如下:

【已解决】记 Vue3+SpringBoot 前后端分离项目部署时的一次跨域问题_第3张图片

解决跨域问题

在后端 SpringBoot 服务中添加配置类解决跨域问题:

@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")  // 拦截所有的请求
                .allowedOrigins("*")  // 可跨域的域名,可以为 *
                .allowCredentials(true)
                .allowedMethods("*")   // 允许跨域的方法,可以单独配置
                .allowedHeaders("*");  // 允许跨域的请求头,可以单独配置
    }
    
}

但是当前端工程访问时,依然显示跨域问题,查看后端日志输出,找到输出的日志,异常信息如下:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalArgumentException: When allowCredentials is true, allowedOrigins cannot contain the special value "*" since that cannot be set on the "Access-Control-Allow-Origin" response header. To allow credentials to a set of origins, list them explicitly or consider using "allowedOriginPatterns" instead.

org.springframework.web.util.NestedServlet异常:请求处理失败;嵌套异常java.lang.IollegalArgumentException:当allowCredentials为true时,allowedOrigins不能包含特殊值“*”,因为该值不能在“Access Control Allow Origin”响应标头上设置。要允许一组来源的凭据,请明确列出它们,或者考虑使用“allowedOriginPatterns”。

重新修改配置类:

@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")  // 拦截所有的请求
                .allowedOriginPatterns("*")  // 使用 allowedOriginPatterns
                .allowCredentials(true)
                .allowedMethods("*")   // 允许跨域的方法,可以单独配置
                .allowedHeaders("*");  // 允许跨域的请求头,可以单独配置
    }

}

重启 SpringBoot 服务,前端再次访问接口,成功访问,解决跨域问题:

【已解决】记 Vue3+SpringBoot 前后端分离项目部署时的一次跨域问题_第4张图片

此时响应头如下:

【已解决】记 Vue3+SpringBoot 前后端分离项目部署时的一次跨域问题_第5张图片

你可能感兴趣的:(SpringBoot,spring,boot,后端,java)