VUE3前端与SpringBOOT后端跨域解决

问题

        因为是第一次尝试前后端分离项目,之前完成了前端中包括登录、注册以及项目需要的一些核心功能。但是项目缺人所以又开始搞后端,准备先连接登录功能。前后端交互无非就是前端向后端发请求,同时携带特定的参数,而后端则根据前端的请求路径以及参数返回相应的数据,但这是理论上的,实际操作的时候,被如何正确使用Axios向后端某个路由发数据困扰许久。

前后端跨域

        跨域分为三种:

                端口跨域:源地址http:127.0.0.1:8848 目的地址 http://127.0.0.1:8080

                域名跨域:源地址http:127.0.0.1:8848 目的地址 http://22.33.55.66:8080

                协议跨域:源地址http:127.0.0.1:8848 目的地址 https://22.33.55.66:8080

正确实现

        在前端配置Axios的baseURL为"/api",然后为它设置一个代理"http://localhost:8080"(后端地址)

# 开发环境接口地址
VITE_API_URL = /api

# 开发环境跨域代理,支持配置多个
VITE_PROXY = [["/api","http://localhost:8080"]]

        在后端设置user的Controller的路由为"auth",设置login功能的路由为"login"

@RestController
@RequestMapping("auth")
@Tag(name = "auth", description = "认证相关的Controller")
public class AuthController {
    private final AuthService authService;

    @Autowired
    public AuthController(AuthService authService) {
        this.authService = authService;
    }

    @Operation(
            method = "POST",
            description = "用户登录",
            requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
                    content = @Content(mediaType = "application/json")
            ),
            security = @SecurityRequirement(name = "", scopes = ""),
            summary = "用户登陆"
    )
    @PostMapping("login")
    public ResponseEntity<LoginVO> login(@RequestBody LoginParams login) {
        ResponseEntity<LoginVO> entity;
        System.out.println("");
        try {
            String token = authService.auth(login.getUsername(), login.getPassword());
            entity = ResponseWrapper.responseEntityAccept(new LoginVO(token));
        } catch (UserLoginErrorException e) {
            entity = ResponseWrapper.responseEntityFail(e.getMsg());
        }
        return entity;
    }
}

        配置axios的url为"auth/login"(这个url,刚才设置的是baseURL),PROT1为auth

/**
 * @name 登录模块
 */
// 用户登录
export const loginApi = (params: Login.ReqLoginForm) => {
  return http.post<Login.ResLogin>(PORT1 + `/login`, params, { loading: false }); // 正常 post json 请求  ==>  application/json

};

问题

        设置Axios的baseURL为http://localhost:8080

        这种方式成功地实现了登录功能,但是当我想要退出登录的时候发现一直出现跨域问题,因为源地址为http://localhost:8848而目标地址为http://localhost:8080出现了端口跨域,所以不进行跨域配置便无法成功响应。(bug修复了,复原不回去了,就不贴图了)

        设置Axios的baseURL为/auth

        此时通过查阅资料似乎已经理解到了代理的用处,于是想设置baseURL为auth,然后让所有带有auth的目的地址都代理到http://localhost:8080,这种方式仍然不奏效,虽然已经能够请求到后端的接口了,但是请求的路由错了,因为还是没有理解到使用vite.config.ts创建代理的时候下面这段代码的含义。

ewrite: path => path.replace(new RegExp(`^${prefix}`), ""),

正确思路     

        前端项目使用vite进行搭建,在vite.config.ts中有一个字段server是专门用于配置服务器的,我们可以使用该配置来解决跨域问题。请看下面的代码

/**
 * 创建代理,用于解析 .env.development 代理配置
 * @param list
 */
export function createProxy(list: ProxyList = []) {
  const ret: ProxyTargetList = {};
  for (const [prefix, target] of list) {
    const httpsRE = /^https:\/\//;
    const isHttps = httpsRE.test(target);

    // https://github.com/http-party/node-http-proxy#options
    ret[prefix] = {
      target: target,
      changeOrigin: true,
      ws: true,
      rewrite: path => path.replace(new RegExp(`^${prefix}`), ""),
      // https is require secure=false
      ...(isHttps ? { secure: false } : {})
    };
  }
  return ret;
}

        在这段代码中,接收一个代理列表而后循环处理每个代理,使用prefix与tartget分别取出代理配置中的源地址与代理地址,而后重新封装成键值形式,其中最为关键的是rewrite:XX,这段代码的意思,是将最终请求地址中的源地址去掉,比如配置的时候源地址为/api,代理地址为http://localhost:8080,那么如果不将/api去掉,在最终的请求地址中就会多一个/api,就无法正确地发送请求。

猜你喜欢

转载自blog.csdn.net/2201_75875170/article/details/133966584