前言
跨域对于前后端开发来说是一个老生常谈的问题了。客户端与服务端通信时协议不同、域名不同、端口不同都会产生跨域问题。
值得一说的是跨域是源于浏览器的同源策略,也就是浏览器做了访问限制。而 XMLHttpRequest 请求和 Fetch API 都遵循同源策略。所以跨域也只发生在 XHR 请求和 Fetch请求。像 script 标签的 src 请求是不会产生跨域的,这也就是为什么 jsonp 可以解决跨域。 但是 jsonp 只能解决 get 请求的跨域问题。
大多数情况下,只需后端配置 cors (Cross-origin resource sharing ,中文译为跨域资源共享)即可解决跨域问题。也就是要依赖于后端才能解决跨域问题。那么前端想要本地调式,如何不依赖于后端解决跨域问题昵?
cors 是一种机制,该机制是使用 HTTP 头来告诉浏览器,允许运行在一个源上的 web 应用访问不同源上的资源。 除了 cors 的方案外,还可以通过配置代理来解决跨域问题,即把服务器的域名代理成本地进行请求,那么请求的就是本地接口,就不会产生跨域问题。
前端配置跨域代理有两种方式。
一、使用中间件 http-proxy-middleware 配置跨域代理
- 安装 http-proxy-middleware
npm install http-proxy-middleware --save-dev
- 在 src 目录下新建 setupProxy.js 文件,内容如下。
const {createProxyMiddleware} = require('http-proxy-middleware'); module.exports = function (app) { app.use('/httpServer', createProxyMiddleware({ target: 'http://10.0.0.0:8080',//后台服务器地址 changeOrigin: true, pathRewrite: { '^/httpServer': 'http://localhost:3000',//本地地址 }, })) }
实现原理是使用 http-proxy-middleware 的 createProxyMiddleware 方法。
其中:target 是服务器地址。changeOrigin 是将主机的源更改为目标URL,默认为 false。pathRewrite 是代理的目标地址。即如果代理到本地,就写本地地址。以上代理配置将会匹配所有以 /httpServer 开始的路径。并将服务器 ‘http://10.0.0.0:8080’ 上面的 ‘/httpServer’ 请求代理到本地’http://localhost:3000’。
-
示例
const { createProxyMiddleware } = require('http-proxy-middleware') module.exports = function(app) { app.use('/zfbz/', createProxyMiddleware({ target: 'http://10.98.1.211:41003', changeOrigin: true, })) app.use('/login/', createProxyMiddleware({ target: 'http://10.98.1.211:41003', changeOrigin: true, })) app.use('/pub_getInfo', createProxyMiddleware({ target: 'http://10.98.1.211:41003', changeOrigin: true, })) app.use('/api', createProxyMiddleware({ target: 'http://10.98.1.211:41003', changeOrigin: true, })) }
二、使用 webpack/dev 配置跨域代理
在使用和配置 webpack 时一般都会安装 webpack-dev-server。
在 webpack.config.js 中配置如下:
module.exports = {
devServer:{
proxy:{
'/httpServer':{
target: 'http://10.0.0.0:8080',//后台服务器地址
changeOrigin: true,//target为域名时必须设置此项
secure: false,//设置支持 https 协议的代理
pathRewrite: {
'^/httpServer': 'http://localhost:3000',//本地地址
},
}
}
}
参数说明:
‘/httpServer’
捕获 API 的标志,如果 API 中包含 ‘/httpServer’ 字符串,就会开始匹配代理。
比如 ‘/httpServer/user/login’。就会被代理到 ‘http://10.0.0.0:8080/httpServer/user/login’
target
代理的跨域地址,就是需要被代理的跨域地址。
可以是域名,也跨域是 IP。如果是域名,则需要加上changeOrigin: true,否则代理会失效。
pathRewrite
重写路径,修改原始请求路径。也就是把服务器地址代理同源地址。
secure
不检查安全问题,设置后,可以运行在 HTTP 上,可以使用无效正式的 HTTPS 服务。
三、对比
其实可以看到方法一和方法二的配置基本相同。因为方式二也是通过 http-proxy-middleware 中间件来实现的,只不过可以直接在 webpack 中进行配置。那在使用上二者有什么区别昵?
如果 webpack.config.js 文件暴露在外,可以使用第二种方法。如果使用 create-react-app 创建的脚手架 react 项目,webpack 配置文件没有对外暴露,就可以使用第一种方法