前端开发过程中跨域的解决方案

为什么会出现跨域

在前端开发的过程中,在使用 ajax 向后端发送请求经常会出现这样一种情况。

这种现象是浏览器的同源策略导致的,同源策略是浏览器的核心基础安全策略。

浏览器的同源策略

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

如果两个 URL 的 protocol、port 和 host 都相同的话,则这两个 URL 是同源。但凡其中一个存在不同的时候,就违反了同源策略,浏览器将会拦截这次请求的结果(但实际上后台服务器是接收到了这次请求并作出了响应,只是浏览器拦截了请求的结果。)

下图给出了与 URL http://store.company.com/dir/page.html 的源进行对比的示例:

因此出于浏览器同源策略的影响,不是同源的两个 URI 进行请求时就会出现跨域的问题。
目前真正的解决方案往往是部署时由服务端来通过、比如配置 CORS,nginx 方向代理解决,但在开发阶段,作为前端工程师在前后端分离的项目里可以使用配置反向代理来解决该问题。

反向代理的原理

我们以浏览器的服务是 http://localhost:3000 后台服务器的服务是 http://localhost:8080 为例分析,由于二者 URI 的端口不同,违反了同源策略,所以在 3000 端口的服务发起的 ajax 请求就会因为违反浏览器的同源策略而拒绝访问。

但是同源的策略仅针对浏览器与服务器之间存在,我们可以在浏览器和服务器之间建立一个代理服务器来作桥梁 ,现在我们给代理服务器取 A 真正的后台服务器取 B,
设置的服务器 A 的协议端口与浏览器的服务一致,这样就避免了同源策略的拦截,并且服务器 A 与服务器 B 之间是不存在同源拦截的,因此,从浏览器发出请求是向 A 发送,A 立即向 B 发送请求,B 的返回值会直接给服务器 A,因为不存在同源所以不会拦截,B 服务器与浏览器的 URL 同源,故而也不会拦截,这样就解决了浏览器跨域拦截的问题。

现在大多数的项目都是前后端分离的项目,前端项目往往都是如 webpack 或者 vite 构建的项目,笔者大多是在 webpack 配置,故以 webpack 配置方法为例

webpack 配置代理服务器

大多数框架的配置都是 webpack 的,因此这里以 webpack 配置为例进行讲解,对于具体的框架可以查询如 vue-cli 如何配置 webpack react 同理

proxy 配置就是 webpack 提供的代理服务器的配置项,使用/api 这个路由映射真正的后台服务器。

  • target: 是目标服务器真正的后台服务器的地址
  • pathRewrite: 重写请求路径中的/api 为空
  • changeOrigin 设置为 true 是应对 如果后台服务器也进行了同源校验,如果真正的后台服务开启了同源校验 ,设置为 true 可以欺骗真正后台服务器 8080 代理服务器也是 8080 的,但实际上代理服务器其实是在 3000 端口的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// webpack.config.js
module.exports = {
devServer: {
proxy: {
"/api": {
target: "http://localhost:8080",
pathRewrite: { "^/api": "" },
changeOrigin: true,
},
},
},
};

// ajax请求 --- 映射的路由是 http://localhost:8080/api/login
// 但实际上服务器上是没有api的因此webpack下所以要配置pathRewrite将api这个路由进行重写""
// 这时完整的映射是http://localhost:8080/login
axios.get("/api/login");

前端开发过程中跨域的解决方案
https://sunburst89757.github.io/2022/11/16/crossOrigin/
作者
Sunburst89757
发布于
2022年11月16日
许可协议