一篇文章图文并茂地带你粗略了解 devServer proxy 原理
devServer proxy 原理
前言
笔者在网络上查询 devServer
原理的时候,竟然网上没有一篇这样的文章,笔者斗胆用自己的知识阐述一下 devServer
是如何实现跨域的(注意,本篇文章并非完整实现proxy
,亦或是实现devserver
的各个功能,仅仅是对 devServer
proxy
部分做个粗略的原理解读。
在阅读本文之前,希望你有基础的 node.js
知识以及 js
知识。
同源政策
浏览器有同源政策,对不同域(即协议,主机,端口任何一个不同的 URL)的 http
请求进行了限制,原先只能用 jsonp
进行跨域,因为浏览器的同源政策并不对 jsonp
生效,也就是不对下面这两个标签等生效,因此可以采用 script
标签或者 img
标签发送请求,但是仅仅局限于 GET
请求
<script src="..."></script>
<img src="..."></img>
后来主流浏览器渐渐支持了 CORS
CORS
CORS 是跨域资源共享的意思。
从 ajax2.0
之后,可以用 XMLHttpRequest
发送跨域请求,前提是服务器端必须设置好
'Access-Control-Allow-Origin': '*', // 允许的域 也可以具体是某个 ip 地址
'Access-Control-Allow-Methods': '*', // 允许的方法 也可以是具体的某个方法 例如 GET
'Access-Control-Allow-Headers': 'Content-Type'
一旦服务器设置好这些头部信息返回,也就代表了服务器允许跨域,这个时候我们就可以通过浏览器请求到服务器的数据。
注意
同源政策是浏览器的政策,也就是说服务器可以不遵守这个政策,也就是说服务器之间可以跨域共享资源。借助这一特性,我们可以进行代理转发,利用 node.js
监听 web
服务器开启的端口,并进行代理转发。
例子
- 先写一下最基础的
html
文件,创建一个按钮做请求发送
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="./index.js"></script>
<title>devServer proxy</title>
</head>
<body>
<button id="btn">点击发个请求</button>
</body>
</html>
- 在
html
同级目录下创建js
文件,书写请求代码
window.onload = () => {
const btn = document.querySelector("#btn");
btn.addEventListener("click", () => {
const xhr = new XMLHttpRequest();
const data = { name: "huro" };
xhr.open("POST", "http://localhost:5501");
xhr.send({ data });
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText);
}
}
});
};
并启用 live server
等启动一个 web
服务器,假设端口为 5500
- 开启
proxy
端口监听,并做代理转发
需要用到 http
库,进行 http
请求以及监听端口,详情请读者看代码注释。
http
库是 node
自带的库,不需要下载。可以直接使用。
const http = require("http");
const server = http.createServer((req, res) => {
// 为了 CORS 设置的头部信息
res.writeHead(200, {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': '*',
'Access-Control-Allow-Headers': 'Content-Type'
})
// 代理转发 这里的目标服务器是 localhost:4000
http.request({
host: 'localhost',
port: 4000,
url: '/',
method: req.method,
headers: req.headers,
},
response => {
let body = ''
response.on("data", chunk => {
body += chunk;
})
response.on("end", () => {
res.end(body);
})
})
.end();
})
server.listen(5500); // 监听 `web` 服务器的端口
书写好代码后启动一个 cmd
然后 node <这个文件的名称>
即可。
- 开启服务器端口监听
const http = require("http");
const server = http.createServer((req, res) => {
res.end('cool')
})
server.listen(4000);
经过上述配置,点击按钮,成功返回 cool
到控制台,并在 chrome
浏览器的 network
进行查看,发现请求地址是 localhost:5500
,实际上已经帮我们做代理转发了。
总结
本篇文章只是介绍了代理转发的过程,实际上为了要处理不同的请求,还需要花费大量的力气,webpack-dev-server
内部使用的是 http-proxy-middleware
而这个库用的又是 node-http-proxy
,感兴趣的读者可以自行阅读源码。
另外在项目中实际使用的时候,如果服务端已经配置了跨域,也可以不用配置 dev-server
的 proxy
,不过建议配置,原因的话是因为还提供 rewrite
path
等其他功能。