业务场景
前后端数据交互时会存在跨域的情况,这个时候就比较难受。传统的解决方案有三种,分别是
Jsonp:但是只能处理get请求
后端CORS:配置注解@CrossOrigin(用的最多)
反向代理 :纯前端处理跨域,其原理是利用后端没有跨域限制,咱们呢只负责请求自己的服务器,让自己的服务器请求要访问的服务器地址
我们由于项目需要经常会需要对不同域名、不同子域的网站接口发起请求,有时甚至是对于同一域名的不同端口发起请求,此时我们经常看到以下报错:
Access to XMLHttpRequest at 'xxx' from origin 'xxx' has been blocked by CORS
policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
是的,错误的原因就是你跨域了。
解决跨域
方案一:
react简单解决跨域可以直接在 package.json
中添加 proxy
属性
添加一行配置(注意,每个配置项之间用“,”分割,配置完后必须重启才能生效)
"proxy":"http://localhost:5000"
- 优点:配质检单,前端请求资源的时候可以不加任何前缀。
- 缺点:只能配置一个代理。
方案二:
如果你已经进行了 npm run eject
,建议你直接修改 config>webpackDevServer.config.js
:
module.exports = function (proxy, allowedHost) {
const disableFirewall =
!proxy || process.env.DANGEROUSLY_DISABLE_HOST_CHECK === 'true';
// 配置proxy对象解决跨域
proxy = {
...proxy,
'/api': {
target: 'http://localhost:3000', // 后台服务地址以及端口号
changeOrigin: true, //是否跨域
pathRewrite: { '^/api': '/' },// 代理名称
secure: false
},
}
return {
......
}
方案三(推荐):
安装 http-proxy-middleware
:
npm install http-proxy-middleware
或者
yarn add http-proxy-middleware
这里注意,http-proxy-middleware 模块是有版本区别的,默认安装最新版本,然后在 src 目录下新建 setupProxy.js
:
const { createProxyMiddleware } = require("http-proxy-middleware");
module.exports = function (app) {
app.use(
"/api", // 遇到以 /api1 为前缀的请求,就会触发这个代理
createProxyMiddleware({
target: "http://localhost:3000", // 请求转发的目标,后台服务地址以及端口号
changeOrigin: true, // 是否开启代理
pathRewrite: {
"/api": "", // 代理名称
},
})
),
//=============配置多个代理=============
app.use(
'/reqPro', // 需要代理的接口路径
createProxyMiddleware({
target: 'http://10.88.7.7:8022/ierp/', // 目标服务器地址
changeOrigin: true, // 是否改变源地址
pathRewrite: {
'^/reqPro': '', // 重写路径
},
})
);
};
- 优点:可以配置多个代理,可以灵活的控制请求是否走代理。
- 缺点:配置繁琐,前端请求资源的时候必须加前缀。
重新 npm run start
即可解决跨域
方案四:
如果你使用的是 Vite 并非Webpack打包工具,直接使用server的proxy属性即可
//vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
server: {
host: "0.0.0.0", //打开显示本地地址
open: true,// 是否自动启动浏览器
port: 3000,//端口号
//代理解决跨域
proxy: { // 本地开发环境通过代理实现跨域
// 正则表达式写法
'/api': {
target: 'http://xxx.xxx.xxx.xxx:9999', // 后端服务实际地址
changeOrigin: true, //开启代理
rewrite: (path) => path.replace(/^\/api/, '')
}
}
}
})
注:此跨域解决方法同时也适用于Vue3+Vite的项目中