SpringBoot+Vue前后端分离跨域问题

11 篇文章 1 订阅
5 篇文章 0 订阅


前言

作为前后端分离的项目,跨域问题是无法避免的,在开发中,通常我们都会在后端进行全局跨域的处理,今天向大家介绍几种跨域问题的解决方法​。

一、CORS是什么?

CORS即跨源资源共享,它定义了一种浏览器和服务器交互的方式来确定是否允许跨域请求。它是一个妥协,有更大的灵活性,但比起简单地允许所有这些的要求来说更加安全。但是CORS也具有一定的风险性,比如请求中只能说明来自于一个特定的域但不能验证是否可信,而且也容易被第三方入侵。 这里一般需要后端配合,开启cors。

二、解决方法

1.后端解决方法

1.1.注解(局部跨域)

后台服务端添加注解**@CrossOrigin**,但是重复代码过多,而且维护麻烦,不推荐使用

@RestController
@RequestMapping("/user")
@CrossOrigin(origins = "*")
public class AdminUserController {}

1.2.返回新的 CorsFilter(全局跨域)

在任意配置类,返回一个 新的 CorsFIlter Bean ,并添加映射路径和具体的CORS配置路径。

@Configuration
public class GlobalCorsConfig {
  @Bean
  public CorsFilter corsFilter() {
    //1. 添加 CORS配置信息
    CorsConfiguration config = new CorsConfiguration();
    //放行哪些原始域
    config.addAllowedOrigin("*");
    //是否发送 Cookie
    config.setAllowCredentials(true);
    //放行哪些请求方式
    config.addAllowedMethod("*");
    //放行哪些原始请求头部信息
    config.addAllowedHeader("*");
    //暴露哪些头部信息
    config.addExposedHeader("*");
    //2. 添加映射路径
    UrlBasedCorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource();
    corsConfigurationSource.registerCorsConfiguration("/**",config);
    //3. 返回新的CorsFilter
    return new CorsFilter(corsConfigurationSource);
  }
}

在filter中的preHandle进行预处理

@WebFilter(filterName = "CorsFilter")
public class CorsFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "*");
        chain.doFilter(req, res);
    }
}

1.3. 重写 WebMvcConfigurer(全局跨域)

CrossConfiguration

@Configuration
public class CorsConfiguration implements WebMvcConfigurer {

	@Override
	public void addCorsMappings(CorsRegistry registry) {
		registry.addMapping("/**")
				.allowedHeaders("*")
				.allowedMethods("*")
				.allowedOrigins("*")
				.allowCredentials(true)
				.maxAge(3600);

	}
}

1.4 手动设置响应头(局部跨域)

使用 HttpServletResponse 对象添加响应头(Access-Control-Allow-Origin)来授权原始域,这里 Origin的值也可以设置为 “*”,表示全部放行。

@GetMapping("/index")
public String index(HttpServletResponse response) {
  response.addHeader("Access-Allow-Control-Origin","*");
  return "index";
}

1.5 使用自定义filter实现跨域

编写一个过滤器

@WebFilter(filterName = "CorsFilter")
public class CorsFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "*");
        chain.doFilter(req, res);
    }
}

2.前端解决方法

2.1. vue.config.js配置项

使用vue-cli创建的vue 项目
vue3版本之后处理跨域问题需要在package.json的同级目录下创建vue.config.js文件,
编写相关的跨域配置

module.exports = {
  configureWebpack: {
    resolve: {
      //文件别名
      alias: {
        api: '@/api',
        assets: '@/assets',
        components: '@/components',
        layouts: '@/layouts',
        router: '@/router',
        store: '@/store',
        utils: '@/utils',
        views: '@/views'
      }
    }
  },
  devServer: {
    //端口
    port: 8081,
    //后端接口
    proxy: {
      '/api': {
        target: 'http://localhost:8099', // 目标代理接口地址
        changeOrigin: true, // 开启代理,在本地创建一个虚拟服务端
        // ws: true, // 是否启用websockets
        pathRewrite: {
          '^/api': ''
        }
      }
    }
  }
}

因为在vue.config.js文件之中配置的代理路径是api,所以我们在封装的axios请求中需要将baseURL设置为相同的**/api**
封装的axios请求js如下

//配置axios
import axios from 'axios'

const instance = axios.create({
  baseURL: '/api',
  timeout: 6000
})
export  default instance

在请求接口文件中引用即可实现跨域

上面配置中,我们根据实际情况只需要修改proxyTable对于配置即可。
假设我后端请求地址是http://localhost:8090,所有api的接口url都以/api开头。所以首先需要匹配所有以/api开头的.然后修改target的地址为http://localhost:8090。最后修改pathRewrite地址。将前缀 ‘^api’ 转为 ‘/api’。如果本身的接口地址就有 ‘/api’ 这种通用前缀,
就可以把 pathRewrite 删掉。注意这个方式只能在开发环境中使用。


3.服务器解决方法

3.1.Nginx

在nginx的配置文件nginx.conf中进行配置
将根目录指向build之后的dist文件夹
配置和前端类似的接口转发

server {
    listen 80;
    server_name localhost;
    
    root /usr/web/dist/;#"绝对路径(dist文件夹)"

    location / {
        root $root
        index index.html
    }
    location /api {#api映射
        add_header 'Access-Contro-Allow-Origin' '*';
        proxy_pass  https://www.csdn.net/;
    }
}

总结

理解跨域的问题产生的本质就是代理,就不难解决这个问题了
以上三种方法是最常见,也是最有效的解决跨域的方法

后续会持续更新!

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值