單線程node.js代理中間件,用於連接,快速和瀏覽器同步
Node.js代理簡單。 輕松配置代理中間件連接,快速,瀏覽器同步等。
由流行的Nodejitsu http代理提供。
TL;DR
代理/ api請求到http://www.example.org
1 var express = require('express'); 2 var proxy = require('http-proxy-middleware'); 3 4 var app = express(); 5 6 app.use('/api', proxy({target: 'http://www.example.org', changeOrigin: true})); 7 app.listen(3000);
可以使用所有http-proxy
選項,以及一些額外的http-proxy-middleware
選項。
提示:將基於名稱的虛擬托管網站的選項changeOrigin
設置為true
。
內容列表
- 安裝
- 核心概念
- 舉個栗子
- 上下文匹配
- 選項
- http-proxy-middleware選項
- http-proxy事件
- http-proxy選項
- 速記
- app.use(path, proxy)
- WebSocket
- 外部Websocket升級
- 工作示例
- Recipes
- 兼容的服務器
- 測試
- 更新日志
- License
Install
$ npm install --save-dev http-proxy-middleware
proxy([context,] config)
var proxy = require('http-proxy-middleware'); var apiProxy = proxy('/api', {target: 'http://www.example.org'}); // \____/ \_____________________________/ // | | // context options // 'apiProxy' is now ready to be used as middleware in a server.
- context:確定應將哪些請求代理到目標主機。 (更多關於上下文匹配)
- options.target:目標主機到代理。 (協議+主機)
(http-proxy-middleware
配置選項的完整列表)
proxy(uri [, config])
// shorthand syntax for the example above: var apiProxy = proxy('http://www.example.org/api');
更多關於速記配置。
舉個栗子
使用express服務器的示例。
// include dependencies var express = require('express'); var proxy = require('http-proxy-middleware'); // proxy middleware options var options = { target: 'http://www.example.org', // target host changeOrigin: true, // needed for virtual hosted sites ws: true, // proxy websockets pathRewrite: { '^/api/old-path' : '/api/new-path', // rewrite path '^/api/remove/path' : '/path' // remove base path }, router: { // when request.headers.host == 'dev.localhost:3000', // override target 'http://www.example.org' to 'http://localhost:8000' 'dev.localhost:3000' : 'http://localhost:8000' } }; // create the proxy (without context) var exampleProxy = proxy(options); // mount `exampleProxy` in web server var app = express(); app.use('/api', exampleProxy); app.listen(3000);
Context matching
提供一種替代方式來決定哪些請求應該被代理;如果您無法使用服務器的路徑參數來裝載代理,或者需要更多的靈活性。
RFC 3986路徑用於上下文匹配。
foo://example.com:8042/over/there?name=ferret#nose \_/ \______________/\_________/ \_________/ \__/ | | | | | scheme authority path query fragment
- 路徑匹配
proxy({...})
- 匹配任意路徑,所有的請求都會被代理。proxy('/', {...})
-匹配任意路徑,所有的請求都會被代理。proxy('/api', {...})
-匹配所有以/api
開始的路徑。
- 多重路徑匹配
proxy(['/api', '/ajax', '/someotherpath'], {...})
-
通配符路徑匹配
對於細粒度控制,您可以使用通配符匹配。通過micromatch
進行全局模式匹配。訪問micromatch
或glob
更多globbing
示例。proxy('**', {...})
匹配任意路徑,所有的請求都會被代理。proxy('**/*.html', {...})
匹配所有以.html
結尾的任意路徑。proxy('/*.html', {...})
直接匹配絕對路徑下的路徑。proxy('/api/**/*.html', {...})
匹配在/api
路徑下以.html
結尾的請求。proxy(['/api/**', '/ajax/**'], {...})
組合多重路由模式。proxy(['/api/**', '!**/bad.json'], {...})
排除匹配。
- 自定義匹配
為了完全控制,您可以提供一個自定義函數來確定哪些請求應該被代理。
var filter = function (pathname, req) { return (pathname.match('^/api') && req.method === 'GET'); }; var apiProxy = proxy(filter, {target: 'http://www.example.org'})
選項
http-proxy-middleware選項
-
option.pathRewrite:對象/函數,重寫目標的url路徑。對象鍵將被用作RegExp來匹配路徑。
1 // rewrite path 2 pathRewrite: {'^/old/api' : '/new/api'} 3 4 // remove path 5 pathRewrite: {'^/remove/api' : ''} 6 7 // add base path 8 pathRewrite: {'^/' : '/basepath/'} 9 10 // custom rewriting 11 pathRewrite: function (path, req) { return path.replace('/api', '/base/api') }
-
option.router:對象/函數,重新定位特定請求的
option.target
1 // Use `host` and/or `path` to match requests. First match will be used. 2 // The order of the configuration matters. 3 router: { 4 'integration.localhost:3000' : 'http://localhost:8001', // host only 5 'staging.localhost:3000' : 'http://localhost:8002', // host only 6 'localhost:3000/api' : 'http://localhost:8003', // host + path 7 '/rest' : 'http://localhost:8004' // path only 8 } 9 10 // Custom router function 11 router: function(req) { 12 return 'http://localhost:8004'; 13 }
-
option.logLevel:字符串, [‘debug’, ‘info’, ‘warn’, ‘error’, ‘silent’]. 默認:
'info'
-
option.logProvider:函數,修改或者替換日志服務。默認:
'console'
。1 // simple replace 2 function logProvider(provider) { 3 // replace the default console log provider. 4 return require('winston'); 5 } 6 // verbose replacement 7 function logProvider(provider) { 8 var logger = new (require('winston').Logger)(); 9 10 var myCustomProvider = { 11 log: logger.log, 12 debug: logger.debug, 13 info: logger.info, 14 warn: logger.warn, 15 error: logger.error 16 } 17 return myCustomProvider; 18 }
1(已棄用)option.proxyHost:用
option.changeOrigin = true
-
代替。
-
(已棄用)option.proxyTable:用
option.router
代替。 -
http-proxy 事件
訂閱http-proxy事件
-
option.onError:函數,訂閱
http-proxy
的error
事件以進行自定義錯誤處理。1 function onError(err, req, res) { 2 res.writeHead(500, { 3 'Content-Type': 'text/plain' 4 }); 5 res.end('Something went wrong. And we are reporting a custom error message.'); 6 }
option.onProxyRes:函數,訂閱
http-proxy
-
的
proxyRes
-
事件。
1 function onProxyRes(proxyRes, req, res) { 2 proxyRes.headers['x-added'] = 'foobar'; // add new header to response 3 delete proxyRes.headers['x-removed']; // remove header from response 4 } 5 6 7 option.onProxyReq:函數,訂閱http-proxy的proxyReq事件。 8 function onProxyReq(proxyReq, req, res) { 9 // add custom header to request 10 proxyReq.setHeader('x-added', 'foobar'); 11 // or log the req 12 } 13 option.onProxyReqWs:函數,訂閱http-proxy的proxyReqWs事件。 14 function onProxyReqWs(proxyReq, req, socket, options, head) { 15 // add custom header 16 proxyReq.setHeader('X-Special-Proxy-Header', 'foobar'); 17 }
-
option.onOpen:函數,訂閱
http-proxy
-
的
open
-
事件。
1 function onOpen(proxySocket) { 2 // listen for messages coming FROM the target here 3 proxySocket.on('data', hybiParseAndLogMessage); 4 }
-
option.onClose:函數,訂閱
http-proxy
的close
事件。1 function onClose(res, socket, head) { 2 // view disconnected websocket connections 3 console.log('Client disconnected'); 4 }
http-proxy選項
底層http-proxy庫提供以下選項。
- option.target:url字符串將與url模塊解析
- option.forward:url字符串將與url模塊解析
- option.target:傳遞給http(s)請求的對象(參閱Node https代理和http代理對象)
- option.ssl:傳遞給https.createServer()的對象
- option.ws:true / false,如果你想要代理websockets
- option.xfwd:true / false,添加x-forward請求頭
- option.secure:true / false,如果你想要驗證SSL證書
- option.toProxy:true / false,將絕對URL作為
path
(對代理使用代理時很有用) - option.prependPath:true / false,默認:true-指定是否要將目標的路徑預置到代理路徑
- option.ignorePath:true / false,默認:false-指定是否要忽略傳入請求的代理路徑(注意:如果需要,您將必須附加/手動)。
- option.localAddress:用於傳出連接的本地接口字符串
- option.changeOrigin:true / false,默認值:false - 將主機頭的源更改為目標URL
- option.auth:基本認證,即“用戶:密碼”來計算授權頭。
- option.hostRewrite:重寫(301/302/307/308)重定向的位置主機名。
- option.autoRewrite:根據請求的主機/端口重寫(301/302/307/308)重定向的位置主機/端口。默認值:false。
- option.protocolRewrite:重寫位置協議(301/302/307/308)重定向到’http’或’https’。默認值:null。
- option.cookieDomainRewrite:重寫set-cookie標頭的域。可能的值:
-false
(默認):禁止重寫cookie
- 字符串:新域名,比如說cookieDomainRewrite:"new.domain"
。使用cookieDomainRewrite:""
刪除域名。
- 對象:域名到新域名的映射,用”*”匹配所有域名。
舉個栗子:保持一個域名不變,重寫一個域名並且刪除其他的:
cookieDomainRewrite: {
"unchanged.domain": "unchanged.domain",
"old.domain": "new.domain",
"*": ""
} - option.headers:對象,添加請求頭。(比如:
{host:'www.example.org'}
) - option.proxyTimeout:超時時間(毫秒)當代理接收不到目標服務器的返回
速記
當不需要詳細配置時,請使用簡寫語法。當使用速記時,上下文和option.target
將被自動配置。如果需要,仍然可以使用選項。
1 proxy('http://www.example.org:8000/api'); 2 // proxy('/api', {target: 'http://www.example.org:8000'}); 3 4 5 proxy('http://www.example.org:8000/api/books/*/**.json'); 6 // proxy('/api/books/*/**.json', {target: 'http://www.example.org:8000'}); 7 8 9 proxy('http://www.example.org:8000/api', {changeOrigin:true}); 10 // proxy('/api', {target: 'http://www.example.org:8000', changeOrigin: true}); 11
app.use(path, proxy)
如果要使用服務器的app.usepath參數匹配請求;創建並裝載不帶
http-proxy-middleware`上下文參數的代理:
app.use('/api', proxy({target:'http://www.example.org', changeOrigin:true}));
app.use文檔
- express: http://expressjs.com/en/4x/api.html#app.use
- connect:https://github.com/senchalabs/connect#mount-middleware
Websocket
1 // verbose api 2 proxy('/', {target:'http://echo.websocket.org', ws:true}); 3 4 // shorthand 5 proxy('http://echo.websocket.org', {ws:true}); 6 7 // shorter shorthand 8 proxy('ws://echo.websocket.org');
外部WebSocket升級
在以前的WebSocket
示例中,http
代理中間件依賴於初始http
請求以便偵聽http
升級事件。如果需要在沒有初始http
請求的情況下代理WebSockets
,則可以手動預訂服務器的http
升級事件。
1 var wsProxy = proxy('ws://echo.websocket.org', {changeOrigin:true}); 2 3 var app = express(); 4 app.use(wsProxy); 5 6 var server = app.listen(3000); 7 server.on('upgrade', wsProxy.upgrade); // <-- subscribe to http 'upgrade'