解决问题之跨域问题

问题解决: 跨域问题

本文主要介绍的解决方式:

  • Vue 项目中配置代理
  • 后端注解 @CrossOrigin
  • 继承 WebMvcConfigurer 的全局配置类

跨域其实并不是一种问题,而是浏览器的安全机制。在 Web 开发中,由于浏览器的同源策略限制,导致不同源(域、协议、端口)之间的网页访问受到限制或出现安全问题。

协议://域名:端口(如 http://localhost:8080): 同源策略表示协议、域名和端口必须一致。比如在前后端分离项目中,后端项目运行在本机的 8080 端口,前端运行在 80 端口,这样前端访问后端就会因为不同源(端口不同)导致跨域限制。

解决跨域问题可以通过下面几种方式:

  • 跨域资源共享 ( CORS ):服务端设置响应头,允许特定源访问资源;
  • JSONP ( JSON with Padding ):利用 Script 标签可以跨域的特性,在前端页面通过动态创建 Script 标签来获取跨域数据;
  • 代理:后端通过代理将请求转发,避免前端直接跨域请求;
  • 服务器设置跨域规则:配置服务器,使其允许跨域请求访问资源。

方式一:前端配置

  1. Vue 项目,在 vite.config.js 文件中可添加如下代理配置,在该文件最后另起一行进行添加即可。

    module.exports = {
      devServer: {
        proxy: {
          '/api': {
            target: 'http://localhost:8989',
            changeOrigin: true,
            pathRewrite: {
              '^/api': ''
            }
          }
        }
      }
    }
    

    以上配置是将带有 /api 前缀的请求进行代理,将其代理到 ‘http://localhost:8989’,并将 /api 去掉

  2. 如果项目中的 Axios 配置文件 (我的项目中该配置的文件名是 axios.js)有配置 baseURL 完整路径的,则需要将 协议://域名:端口 部分去掉,只保留一个 /api/。这样做的目的是:所有的 Ajax 请求都会加一个 /api/ 前缀,然后所有带有 /api 前缀的又将被代理到 http://localhost:8989,从而避免浏览器的跨域限制。

import axios from 'axios';
// 创建一个 Axios 实例,可以给所有的请求都加上一个 /api 前缀
const http = axios.create({
    baseURL: '/api/'
});
export default http;

方式二:后端注解 @CrossOrigin

前面介绍的是前端配置咯,其实在后端也可以解决跨域问题。

  1. 在控制类上加注解 @CrossOrigin,然后通过 origins 参数指定允许跨域访问的源。
@RestController
@RequestMapping("/api/test")
//@CrossOrigin
@CrossOrigin(origins = {"http://localhost:5173", "https://xxxx.com"})
public class TestController {
//    @CrossOrigin(origins = "http://xxx.icu")
    @GetMapping()
    public String test() {
        return "test success!!!";
    }
}
  • origins: 允许可访问的域列表;

  • maxAge: 准备响应前的缓存持续的最大时间(单位秒);

  • @CrossOrigin 后面不加任何参数,表示允许所有源访问。其后可以通过 origins 参数指定一个或多个域,表示允许这些指定的域进行访问。该注解也可以加在方法上,含义一样,表示允许跨域访问该方法。

方式三:配置全局跨域支持

创建一个继承自 WebMvcConfigurer 的配置类,重写其中的 addCorsMappings 方法来配置允许跨域的规则。(注意类上要加 @Configuration 注解表面这是一个配置类,并将其交由 Spring 容器管理)

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOriginPatterns("*")
                .allowedMethods("*")
                .allowCredentials(true)
                .allowedHeaders("token")
                .maxAge(3600);
    }
}
  • addMapping(“/**”): 指定允许跨域访问的路径,通常是所有路径;

  • allowedOriginPatterns(“*"): 表示允许所有的来源;

  • allowedOrigins(“http://xxx.com”): 表示允许指定的来源,区别在于 allowedOriginPatterns() 可以进行模式匹配,而这个需要指定明确地地址;

  • allowedMethods(“*”): 表示允许所有的 HTTP 方法进行跨域请求;

  • allowedCredentials(true): 允许跨域请求携带身份凭证 (如 cookies、HTTP 认证信息等);

  • allowedHeaders(“token”): 指定了允许跨域请求携带的请求头信息,这里表示只允许携带名为 “token” 的请求头;

  • maxAge(3600): 指定预检请求有效期,即在多久内不需要再发送预检请求,这里是 3600 秒(1 小时)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值