在前端开发过程中,我们经常需要在开发模式下调试代码,但是又想去加载线上的一些数据。这时候经常会遇到跨域的问题,看了许多网上的文章,大多建议用反向代理的方法,且大多使用Nginx,可这东西毕竟不是前端经常用到的东西。对我们前端友好且几乎无缝衔接的当然是 nodeJs了,经过一番资料查找终于成功的使用nodejs反向代理的方式,解决了开发环境加载线上数据遇到的问题。
什么是反向代理
反向代理(Reverse Proxy)实际运行方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。 具体的原理大家可以看下这篇文章,里面把正向代理和反向代理描述的很清楚 正向代理和反向代理。
反向代理解决跨域问题的原理
首先我们需要了解的是,前端处于项目开发过程中最接近用户的一个区域,代码最容易被hack获取解析,也最容易受到攻击。针对这个问题,互联网早期探索者Netscape提出了一个著名的安全策略——同源策略:浏览器限制脚本中发起的跨站请求,要求JavaScript或cookie只能访问同源的资源。这里的同源指的是,域名,协议名,以及端口号相同。正是由于这个机制,才致使我们无法用简单的手段来请求不同域名下的资源。
看到这里你应该明白,为什么会出现跨域问题了,原因就是请求的源和服务端的源不是“同源”,而服务端又没有设置允许的跨域资源共享,所以请求的响应被浏览器给拦截掉了。注意:同源策略是浏览器需要遵循的标准,而如果是服务器向服务器请求就无需遵循同源策略
所以我们可以在本地起一个服务转发我们的请求,通过反向代理服务器可以有效的解决跨域问题,代理服务器需要做以下几个步骤:
1.接受客户端的请求
2.将请求转发给实际的服务器
3.将服务器的响应结果返回给客户端
node + express + http-proxy-middleware 代理服务
node和express就不多介绍了,这东西对于我们前端来说应该是很熟悉了
http-proxy-middleware大家可以点击到github上了解下,网上介绍的用法大多是几年前的了,和最新默认版本的还是有些差别的。我这里用的是: "http-proxy-middleware": "^2.0.3",
搭建服务器,代码如下
var express = require("express");
const proxy = require("http-proxy-middleware");
const app = express();
app.set("port", "3000");//监听3000端口,地址为 http://localhost:3000
app.all("*", function (req, res, next) {
// 解决跨域问题
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With");
res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
if (req.method == "OPTIONS") {
res.send(200);
} else {
next();
}
});
//普通请求
const httpProxy = proxy.createProxyMiddleware("/", {
target: "https://XXX",// http代理跨域目标接口
changeOrigin: true,
logLevel: "debug",
});
//长链接
const wsProxy = proxy.createProxyMiddleware("/", {
target: "wss://XXX",// ws代理跨域目标接口
changeOrigin: true,
ws: true,
logLevel: "debug",
});
createProxyMiddleware 可以写多个,用来区分不同的请求转发到不同的服务器,第一个参数设为“/”,意味着所有 http://localhost:3000/... 的请求都会被转发到 https://XXX/... 若设为“/api”,则所有 http://localhost:3000/api/... 的请求都会被转发到 https://XXX/...
app.use(httpProxy);
app.use(wsProxy);
const server = app.listen(app.get("port"), () => {
console.log(`反向代理已开启,端口:${app.get("port")}`);
});
//长链接请求判断(区分普通请求和长链接)
server.on('upgrade', wsProxy.upgrade);
以上便是nodejs反向代理的全部代码,将以上代码写入一个文件中并运行,一个nodejs代理服务器就成功启动了,之后将我们前端项目的请求的baseURL设置为 http://localhost:3000(普通请求) 和 ws://localhost:3000(长链接) 之后再启动前端项目就可以很方便的在开发环境进行相关测试了,由此前端跨域的问题就解决了。