跨域问题的解决方法

2021-7-21 14:43:43

#前端

92

前言

可恶啊,最近被学校抓回去上短学期了。 没办法,毕竟学位证和毕业证还是挺重要的,所以就只能向公司请假一个星期直到短学期结束了。 本文是在开发学校短学期项目的web端后台管理系统时再次碰到跨域问题时写下的笔记。

同源策略

MDN文档 同源策略是一个重要的安全策略,它用于限制一个origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。

  • 同一协议
  • 同一域名
  • 同一端口
  • 有一个不满足浏览器就会报Access to XMLHttpRequest at 'localhost:8080/user/pcdoctorlogin' from origin 'http://localhost:8081' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, chrome-untrusted, https.的错误

解决方法

后端

  • 一般来讲后端来解决跨域问题是最省事的(对于我们前端来讲)
  • 以java的springBoot框架为例,使用Configuration注解配置
@Configuration
public class GlobalCorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping(\"/**\")  //对哪些格式的请求路径进行跨域处理
                .allowedHeaders(\"*\")    //允许的请求头
                .allowedMethods(\"*\")    //允许的请求方法,如GET,POST
                .maxAge(1800)           //探测请求的有效期
                .allowedOrigins(\"*\");   //支持的域 如localhost:8083
    }
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry){

        registry.addResourceHandler(\"/Document/**\").addResourceLocations(\"\");
        WebMvcConfigurer.super.addResourceHandlers(registry);
    }
}

前端

  • 当然因为我是打算搞前端方向的,前端的几种跨域方式我也将在这介绍一下。

JSONP方法

  • 原理:script 标签不受跨域限制的(其它的还有img,link,src标签)
  • 过程
    • 前端定义一个解析函数(如: jsonpCallback = function (res) )
    • 通过params的形式包装script标签的请求参数,并且声明执行函数(如cb=jsonpCallback)
    • 后端获取到前端声明的执行函数(jsonpCallback),并以带上参数且调用执行函数的方式传递给前端
    • 前端在script标签返回资源的时候就会去执行jsonpCallback并通过回调函数的方式拿到数据了
<script type='text/javascript'>
    window.jsonpCallback = function (res) {
        console.log(res)
    }
</script>
<script src='http://localhost:8080/api/jsonp?id=1&cb=jsonpCallback' type='text/javascript'></script>
  • 优点:兼容性好
  • 缺点:只能执行GET方法

vue-cli跨域解决方法

  • 创建vue.config.js文件
  • 文件配置为如下代码
module.exports = {
  devServer: {
    host: 'localhost',
    port: '8081', // 端口号,如果端口号被占用,会自动加一
    https: false, // https: {type:Bollean}
    open: true, // 配置自动启动浏览器
    // 配置代理
    proxy: {
      \"/api\": {
        target: 'http://localhost:8080', // 想要访问接口域名
        changeOrigin: true, // 开启跨域,在本地创建一个虚拟服务器,然后发送请求的数据,并同时接收请求的数据,这样服务端和服务端进行数据交互就不会有问题
        pathRewrite: {
          \"^/api\": '', // 利用这个地面的值拼接上target里面的地址
        }
      }
    }
  }
}
  • 目前比较常用的,利用代理服务器绕过同源策略