如何使用 express 配合代理轉發請求


如何使用 express 配合代理轉發請求

實現一個 express 接口

const express = require("express");
const app = express();
app.use("/abc/11", (req, res) => {
  res.json(11);
});
app.listen(9007);

現在我們來通過類似 postman 的工具測試一下這個接口:

> http -b :9007/abc/11
11

可以看到服務器正常返回了 11 這個響應內容。

實現一個反向代理.

題外話:什么是正向代理反向代理?
解:直接連代理服務就是正向代理,否則就是反向代理。
ps: 這可能是最精簡的解釋了。

const express = require("express");
const proxy = require("http-proxy-middleware").createProxyMiddleware;
const app = express();
app.use("/", proxy(`http://www.httpbin.org`));
app.listen(9007);

再來請求一下,看到其實是連接了一個我們根本就沒有寫的接口。它是 http://www.httpbin.org/ip 返回的內容。

> http -b :9007/ip
{
    "origin": "88.76.56.14"
}

如何實現某些不代理

假設我需要也能代理,也需要 http://127.0.0.1:9007/abc/11 能返回自己的內容。

const express = require("express");
const proxy = require("http-proxy-middleware").createProxyMiddleware;
const app = express();
app.use("/", proxy(`http://www.httpbin.org`));
app.use("/abc/11", (req, res) => {
  res.json(11);
});
app.listen(9007);
> http -b :9007/abc/11
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>404 Not Found</title>
<h1>Not Found</h1>
<p>The requested URL was not found on the server.  If you entered the URL manually please check your spelling and try again.</p>
*/

請求 /abc/11 得到了一個 404 Not Found 這是為什么?
這說明請求並沒有走我們自己寫的接口,還是被轉發了。但轉發的目標服務器上並沒有這個接口,所以報 404 了。

為了更清晰一點的表示,我們重新寫段代碼:

const express = require("express");
const proxy = require("http-proxy-middleware").createProxyMiddleware;
const app = express();
app.use("/", proxy(`/abc`, { target: `http://www.httpbin.org/anything/` }));
app.use("/abc/11", (req, res) => {
  res.json(11);
});
app.listen(9007);
> http -b :9007/abc
{
    "origin": "88.76.56.14",
}

> http -b :9007/abc/11
{
    "origin": "88.76.56.14",
}
*/

可以看到,其實都去了 /anything/

不妨翻閱官網文檔看看

  • wildcard path matching

    For fine-grained control you can use wildcard matching. Glob pattern matching is done by micromatch. Visit micromatch or glob for more globbing examples.

    • createProxyMiddleware('**', {...}) matches any path, all requests will be proxied.
    • createProxyMiddleware('**/*.html', {...}) matches any path which ends with .html
    • createProxyMiddleware('/*.html', {...}) matches paths directly under path-absolute
    • createProxyMiddleware('/api/**/*.html', {...}) matches requests ending with .html in the path of /api
    • createProxyMiddleware(['/api/**', '/ajax/**'], {...}) combine multiple patterns
    • createProxyMiddleware(['/api/**', '!**/bad.json'], {...}) exclusion

可以發現使用 ! 前綴進行排除,並且路徑支持數組形式。

嘗試一下:

const express = require("express");
const proxy = require("http-proxy-middleware").createProxyMiddleware;
const app = express();
app.use(
  "/",
  proxy([`/abc`, `!/abc/11`], { target: `http://www.httpbin.org/anything/` })
);
app.use("/abc/11", (req, res) => {
  res.json(11);
});
app.listen(9007);

果然,試試就差點逝世。

[HPM] Proxy created: /abc,!/abc/11  -> http://www.httpbin.org/anything/
(node:13660) UnhandledPromiseRejectionWarning: Error: [HPM] Invalid context. Expecting something like: ["/api", "/ajax"] or ["/api/**", "!**.html"]

着重看了一下它的錯誤,發現第一個 /api 和第二個 /api/** 有些特別。

然后我也不知道是啥意思。

那就繼續試試:

const express = require("express");
const proxy = require("http-proxy-middleware").createProxyMiddleware;
const app = express();
app.use(
  "/",
  proxy([`/abc/**`, `!/abc/11`], { target: `http://www.httpbin.org/anything/` }) ); app.use("/abc/11", (req, res) => { res.json(11); }); app.listen(9007);
> http -b :9007/abc
{
    "origin": "88.76.56.14",
}


> http -b :9007/abc/11
11


> http -b :9007/abc/12
{
    "origin": "88.76.56.14",
}

嗯看起來現在沒毛病了,除了 /abc/11 返回了我們自己的內容,其他都是服務器返回的內容。

留一個習題

上面的代碼我們設置了 pathRewrite 參數為 host,以及另一個 pathRewrite 參數。

const express = require('express')
const proxy = require('http-proxy-middleware').createProxyMiddleware
const app = express()
app.use('/', proxy(
  [`/abc/**`, `!/abc/11`], { target: "http://www.httpbin.org", pathRewrite: { "^/abc": "http://www.httpbin.org/anything/", }, }, )); app.use('/abc/11', (req, res) => { res.json(11) }); app.listen(9007);

發送以下請求,結果是什么樣的呢?

> http -b :9007/abc   
???

> http -b :9007/abc/11 
???

> http -b :9007/abc/12
???

參考答案:

> http -b :9007/abc   
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>404 Not Found</title>
<h1>Not Found</h1>
<p>The requested URL was not found on the server.  If you entered the URL manually please check your spelling and try again.</p>


> http -b :9007/abc/11 
11

> http -b :9007/abc/12
{
    "origin": "88.76.56.14",
}

提示:
有沒有想起 webpack devServer 中的 proxy?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM