前后端解决跨域五种方案

2年前 (2022) 程序员胖胖胖虎阿
285 0 0

注明:本文章以前端基于Axios解决和以springboot为基础后端解决方案


首先我们先了解一下跨域

  1. 为什么会出现跨域:出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。
  2. 什么跨域:当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域

我们简单的了解了跨域后直接上正片:怎么解决跨域?

 方案一:前端代理解决跨域

  •  vue代理服务器proxy跨域:通过请求本地的服务器,然后本地的服务器再去请求远程的服务器(后端部署接口的服务器),最后本地服务器再将请求回来的数据返回给浏览器(本地服务器和浏览器之前不存在跨域)

废话上说上代码

我们准备的请求url是:localhost:8001/Axios 响应的结果就是简单的字符串

    @ResponseBody
    @GetMapping("/Axios")
    public String axios(){
        return "hello,world";
    }

 如何在vue里面优雅的解决跨域,路由冲突问题?

简单的代理:打开vue-cil中config中index.js找到代理字段 ,把所有的接口,同意规范为一个入口'api/*',在一定程度上会解决冲突

proxyTable: {
      '/api/*': {  //统一前缀
        targrt:'http://localhost:8001'
      }
<template>
  <div>
      <div >
           <div>{{values}}</div>
      </div> 
  </div>
</template>
<script>
export default {
    name:'frontout',
    data() {
        return {
            values:''
        }
    },
    mounted() {
        this.axios({
            url:'/api/Axios',
            method:'get',
        })
        .then(response=>(this.values=response.data))
        .catch(function(error){
            console.log(error);
        })
    },
}
</script>

 简单的代理已经可以解决单url请求跨域了

 当然单一的匹配并不是我们想要的结果 ,我们就可以使用一下方式来解决这个问题:

proxyTable: {
       '/api/**':{    //注意是双星
        target: "http://localhost:8001",
        changeOrigin: true, //如果设置成true:发送请求头中host会设置成target·
        pathRewrite: {
          '^/api':'/'
        }
      }

 同样会出现每次都要配置/api,当然对各位前端老手来说太简单了,全局默认Url(main.js中)

import Axios from 'axios'
import VueAxios from 'vue-axios'

Vue.use(VueAxios, Axios)
axios.defaults.baseURL='api'
mounted() {
        this.axios({
            url:'/Axios',
            method:'get',
        })

 简洁明了


 方案二:后端解决跨域(4种)

 一.添加映射路径和具体的CORS配置路径

@Configuration
public class GlobalCorsConfig {

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

 二.重写WebMvcConfigurer中addCorsMappings方法(全局跨域)

  @Bean
    public WebMvcConfigurer MyWebMvcConfigurer(){
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")

                        //放行哪些原始域
                        .allowedOrigins("*")
                        .allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"})
                        .allowedHeaders("*")
                        .exposedHeaders("*");
            }
        };

三.添加过滤器 

 

@Component
public class CrosFiter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with,content-type");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

四.添加注解

    @CrossOrigin
    //@CrossOrigin(value = "http://localhost:8001")  //单独作用在url上
    @GetMapping("/Axios")
    public String axios(){
        return "hello,world";
    }

也可以添加在类上

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CrossOrigin {...}

个人还是推荐大家使用前端代理解决跨域 

版权声明:程序员胖胖胖虎阿 发表于 2022年10月8日 上午10:24。
转载请注明:前后端解决跨域五种方案 | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...