node-http-proxy
是一個支援 websocket 的 HTTP 可程式代理程式庫。它適合實現反向代理和負載平衡器等元件。
npm install http-proxy --save
回到頂部
點這裡
回到頂部
透過呼叫createProxyServer
並傳遞options
物件作為參數來建立新代理(此處提供有效屬性)
var httpProxy = require ( 'http-proxy' ) ;
var proxy = httpProxy . createProxyServer ( options ) ; // See (†)
†除非在物件上呼叫listen(..),否則不會建立網頁伺服器。見下文。
將透過四種方法傳回一個物件:
req, res, [options]
(用於代理常規 HTTP(S) 請求)req, socket, head, [options]
(用於代理 WS(S) 請求)port
(為了方便起見,將物件包裝在網頁伺服器中的函數)[callback]
(關閉內部網路伺服器並停止偵聽給定連接埠的函數)然後可以透過呼叫這些函數來代理請求
http . createServer ( function ( req , res ) {
proxy . web ( req , res , { target : 'http://mytarget.com:8080' } ) ;
} ) ;
可以使用 Event Emitter API 監聽錯誤
proxy . on ( 'error' , function ( e ) {
...
} ) ;
或使用回呼API
proxy . web ( req , res , { target : 'http://mytarget.com:8080' } , function ( e ) { ... } ) ;
當請求被代理時,它遵循兩個不同的管道(此處可用),這兩個管道將轉換應用於req
和res
物件。第一個管道(傳入)負責建立和操作將客戶端連接到目標的流。第二個管道(傳出)負責建立和操作流,該流從目標將資料返回到客戶端。
回到頂部
var http = require ( 'http' ) ,
httpProxy = require ( 'http-proxy' ) ;
//
// Create your proxy server and set the target in the options.
//
httpProxy . createProxyServer ( { target : 'http://localhost:9000' } ) . listen ( 8000 ) ; // See (†)
//
// Create your target server
//
http . createServer ( function ( req , res ) {
res . writeHead ( 200 , { 'Content-Type' : 'text/plain' } ) ;
res . write ( 'request successfully proxied!' + 'n' + JSON . stringify ( req . headers , true , 2 ) ) ;
res . end ( ) ;
} ) . listen ( 9000 ) ;
†呼叫listen(..)會觸發Web伺服器的建立。否則,僅建立代理實例。
回到頂部
此範例展示如何使用您自己的 HTTP 伺服器代理請求,並且您也可以使用自己的邏輯來處理該請求。
var http = require ( 'http' ) ,
httpProxy = require ( 'http-proxy' ) ;
//
// Create a proxy server with custom application logic
//
var proxy = httpProxy . createProxyServer ( { } ) ;
//
// Create your custom server and just call `proxy.web()` to proxy
// a web request to the target passed in the options
// also you can use `proxy.ws()` to proxy a websockets request
//
var server = http . createServer ( function ( req , res ) {
// You can define here your custom logic to handle the request
// and then proxy the request.
proxy . web ( req , res , { target : 'http://127.0.0.1:5050' } ) ;
} ) ;
console . log ( "listening on port 5050" )
server . listen ( 5050 ) ;
回到頂部
此範例顯示如何使用您自己的 HTTP 伺服器代理請求,該伺服器透過新增特殊標頭來修改傳出代理請求。
var http = require ( 'http' ) ,
httpProxy = require ( 'http-proxy' ) ;
//
// Create a proxy server with custom application logic
//
var proxy = httpProxy . createProxyServer ( { } ) ;
// To modify the proxy connection before data is sent, you can listen
// for the 'proxyReq' event. When the event is fired, you will receive
// the following arguments:
// (http.ClientRequest proxyReq, http.IncomingMessage req,
// http.ServerResponse res, Object options). This mechanism is useful when
// you need to modify the proxy request before the proxy connection
// is made to the target.
//
proxy . on ( 'proxyReq' , function ( proxyReq , req , res , options ) {
proxyReq . setHeader ( 'X-Special-Proxy-Header' , 'foobar' ) ;
} ) ;
var server = http . createServer ( function ( req , res ) {
// You can define here your custom logic to handle the request
// and then proxy the request.
proxy . web ( req , res , {
target : 'http://127.0.0.1:5050'
} ) ;
} ) ;
console . log ( "listening on port 5050" )
server . listen ( 5050 ) ;
回到頂部
有時,當您從來源伺服器收到 HTML/XML 文件時,您希望在轉送之前對其進行修改。
Harmon 可讓您以串流方式執行此操作,以便將代理程式的壓力降至最低。
回到頂部
var http = require ( 'http' ) ,
httpProxy = require ( 'http-proxy' ) ;
//
// Create a proxy server with latency
//
var proxy = httpProxy . createProxyServer ( ) ;
//
// Create your server that makes an operation that waits a while
// and then proxies the request
//
http . createServer ( function ( req , res ) {
// This simulates an operation that takes 500ms to execute
setTimeout ( function ( ) {
proxy . web ( req , res , {
target : 'http://localhost:9008'
} ) ;
} , 500 ) ;
} ) . listen ( 8008 ) ;
//
// Create your target server
//
http . createServer ( function ( req , res ) {
res . writeHead ( 200 , { 'Content-Type' : 'text/plain' } ) ;
res . write ( 'request successfully proxied to: ' + req . url + 'n' + JSON . stringify ( req . headers , true , 2 ) ) ;
res . end ( ) ;
} ) . listen ( 9008 ) ;
回到頂部
您可以啟動對目標連線的安全 SSL 憑證的驗證(避免自簽章憑證),只需在選項中設定secure: true
即可。
//
// Create the HTTPS proxy server in front of a HTTP server
//
httpProxy . createServer ( {
target : {
host : 'localhost' ,
port : 9009
} ,
ssl : {
key : fs . readFileSync ( 'valid-ssl-key.pem' , 'utf8' ) ,
cert : fs . readFileSync ( 'valid-ssl-cert.pem' , 'utf8' )
}
} ) . listen ( 8009 ) ;
//
// Create the proxy server listening on port 443
//
httpProxy . createServer ( {
ssl : {
key : fs . readFileSync ( 'valid-ssl-key.pem' , 'utf8' ) ,
cert : fs . readFileSync ( 'valid-ssl-cert.pem' , 'utf8' )
} ,
target : 'https://localhost:9010' ,
secure : true // Depends on your needs, could be false.
} ) . listen ( 443 ) ;
//
// Create an HTTP proxy server with an HTTPS target
//
httpProxy . createProxyServer ( {
target : {
protocol : 'https:' ,
host : 'my-domain-name' ,
port : 443 ,
pfx : fs . readFileSync ( 'path/to/certificate.p12' ) ,
passphrase : 'password' ,
} ,
changeOrigin : true ,
} ) . listen ( 8000 ) ;
回到頂部
您可以使用選項中的ws:true
啟動代理程式的 websocket 支援。
//
// Create a proxy server for websockets
//
httpProxy . createServer ( {
target : 'ws://localhost:9014' ,
ws : true
} ) . listen ( 8014 ) ;
您也可以只呼叫ws(req, socket, head)
方法來代理 websocket 請求。
//
// Setup our server to proxy standard HTTP requests
//
var proxy = new httpProxy . createProxyServer ( {
target : {
host : 'localhost' ,
port : 9015
}
} ) ;
var proxyServer = http . createServer ( function ( req , res ) {
proxy . web ( req , res ) ;
} ) ;
//
// Listen to the `upgrade` event and proxy the
// WebSocket requests as well.
//
proxyServer . on ( 'upgrade' , function ( req , socket , head ) {
proxy . ws ( req , socket , head ) ;
} ) ;
proxyServer . listen ( 8015 ) ;
回到頂部
httpProxy.createProxyServer
支援以下選項:
target :要使用 url 模組解析的 url 字串
forward :要使用 url 模組解析的 url 字串
agent :要傳遞給 http(s).request 的物件(請參閱 Node 的 https 代理程式和 http 代理程式物件)
ssl :要傳遞給 https.createServer() 的對象
ws :true/false,如果你想要代理 websocket
xfwd :true/false,新增 x-forward 標頭
secure :true/false,如果您想驗證 SSL 憑證
toProxy :true/false,將絕對 URL 作為path
傳遞(對於代理程式到代理很有用)
prependPath :true/false,預設值:true - 指定是否要將目標路徑新增至代理路徑前面
ignorePath : true/false,預設值: false - 指定是否要忽略傳入請求的代理路徑(注意:如果需要,您必須手動附加 / )。
localAddress :用於綁定傳出連線的本機介面字串
changeOrigin : true/false, 預設值: false - 將主機標頭的來源變更為目標 URL
keepHeaderKeyCase : true/false, 預設值: false - 指定是否要保留回應標頭鍵的字母大小寫
auth :基本驗證,即「使用者:密碼」來計算授權標頭。
hostRewrite :重寫 (201/301/302/307/308) 重新導向上的位置主機名稱。
autoRewrite :根據請求的主機/連接埠重寫 (201/301/302/307/308) 重新導向上的位置主機/連接埠。預設值:假。
protocolRewrite :將 (201/301/302/307/308) 重新導向上的位置協定改寫為「http」或「https」。預設值:空。
cookieDomainRewrite :重寫set-cookie
標頭的網域。可能的值:
false
(預設):停用 cookie 重寫cookieDomainRewrite: "new.domain"
。若要刪除網域,請使用cookieDomainRewrite: ""
。"*"
匹配所有域。例如保持一個域不變,重寫一個域並刪除其他域: cookieDomainRewrite: {
"unchanged.domain": "unchanged.domain",
"old.domain": "new.domain",
"*": ""
}
cookiePathRewrite :重寫set-cookie
標頭的路徑。可能的值:
false
(預設):停用 cookie 重寫cookiePathRewrite: "/newPath/"
。若要刪除路徑,請使用cookiePathRewrite: ""
。若要設定 root 路徑,請使用cookiePathRewrite: "/"
。"*"
來匹配所有路徑。例如,若要保持一條路徑不變,請重寫一條路徑並刪除其他路徑: cookiePathRewrite: {
"/unchanged.path/": "/unchanged.path/",
"/old.path/": "/new.path/",
"*": ""
}
headers :具有要新增至目標請求的額外標頭的物件。
proxyTimeout :傳出代理請求的逾時(以毫秒為單位)
timeout :傳入請求的逾時(以毫秒為單位)
followRedirects :true/false,預設值:false - 指定是否要遵循重定向
selfHandleResponse true/false,如果設定為 true,則不會呼叫任何 webOutgoing 傳遞,並且您有責任透過偵聽和執行proxyRes
事件來適當地傳回回應
buffer :作為請求主體發送的資料流。也許您有一些中間件在代理請求流之前消耗它,例如,如果您將請求的正文讀入名為“req.rawbody”的字段,您可以在緩衝區選項中重新流式傳輸該字段:
'use strict';
const streamify = require('stream-array');
const HttpProxy = require('http-proxy');
const proxy = new HttpProxy();
module.exports = (req, res, next) => {
proxy.web(req, res, {
target: 'http://localhost:4003/',
buffer: streamify(req.rawBody)
}, next);
};
注意: options.ws
和options.ssl
是可選的。 options.target
和options.forward
不能同時缺失
如果您使用proxyServer.listen
方法,則下列選項也適用:
回到頂部
error
:如果對目標的請求失敗,則會發出錯誤事件。我們不會對用戶端和代理之間傳遞的訊息以及代理程式和目標之間傳遞的訊息進行任何錯誤處理,因此建議您監聽錯誤並進行處理。proxyReq
:在發送資料之前發出此事件。它使您有機會更改 proxyReq 請求物件。適用於「網路」連接proxyReqWs
:在發送資料之前發出此事件。它使您有機會更改 proxyReq 請求物件。適用於“websocket”連接proxyRes
:如果對目標的請求得到回應,則會發出此事件。open
:建立代理 websocket 並將其透過管道傳輸到目標 websocket 後,會發出此事件。close
:代理 websocket 關閉後會發出此事件。proxySocket
:已棄用,轉而使用open
。 var httpProxy = require ( 'http-proxy' ) ;
// Error example
//
// Http Proxy Server with bad target
//
var proxy = httpProxy . createServer ( {
target : 'http://localhost:9005'
} ) ;
proxy . listen ( 8005 ) ;
//
// Listen for the `error` event on `proxy`.
proxy . on ( 'error' , function ( err , req , res ) {
res . writeHead ( 500 , {
'Content-Type' : 'text/plain'
} ) ;
res . end ( 'Something went wrong. And we are reporting a custom error message.' ) ;
} ) ;
//
// Listen for the `proxyRes` event on `proxy`.
//
proxy . on ( 'proxyRes' , function ( proxyRes , req , res ) {
console . log ( 'RAW Response from the target' , JSON . stringify ( proxyRes . headers , true , 2 ) ) ;
} ) ;
//
// Listen for the `open` event on `proxy`.
//
proxy . on ( 'open' , function ( proxySocket ) {
// listen for messages coming FROM the target here
proxySocket . on ( 'data' , hybiParseAndLogMessage ) ;
} ) ;
//
// Listen for the `close` event on `proxy`.
//
proxy . on ( 'close' , function ( res , socket , head ) {
// view disconnected websocket connections
console . log ( 'Client disconnected' ) ;
} ) ;
回到頂部
var proxy = new httpProxy . createProxyServer ( {
target : {
host : 'localhost' ,
port : 1337
}
} ) ;
proxy . close ( ) ;
回到頂部
如果您想在收到proxyRes
後處理自己的回應,可以使用selfHandleResponse
來完成。如下所示,如果使用此選項,您可以攔截並讀取proxyRes
,但您還必須確保回覆res
本身,否則原始用戶端將永遠不會收到任何資料。
var option = {
target : target ,
selfHandleResponse : true
} ;
proxy . on ( 'proxyRes' , function ( proxyRes , req , res ) {
var body = [ ] ;
proxyRes . on ( 'data' , function ( chunk ) {
body . push ( chunk ) ;
} ) ;
proxyRes . on ( 'end' , function ( ) {
body = Buffer . concat ( body ) . toString ( ) ;
console . log ( "res from proxied server:" , body ) ;
res . end ( "my response to cli" ) ;
} ) ;
} ) ;
proxy . web ( req , res , option ) ;
透過此附加模組可以使用代理表 API,它允許您定義一組規則,將匹配的路由轉換為反向代理將與之通訊的目標路由。
$ npm test
標誌由迭戈·帕斯誇裡創建
回到頂部
master
不同)回到頂部
麻省理工學院許可證 (MIT)
版權所有 (c) 2010 - 2016 Charlie Robbins、Jarrett Cruger 及貢獻者。
特此免費授予任何獲得本軟體和相關文件文件(「軟體」)副本的人不受限制地使用本軟體,包括但不限於使用、複製、修改、合併的權利、發布、分發、再授權和/或銷售軟體的副本,並允許向其提供軟體的人員這樣做,但須滿足以下條件:
上述版權聲明和本授權聲明應包含在本軟體的所有副本或主要部分中。
本軟體以「現況」提供,不提供任何明示或暗示的保證,包括但不限於適銷性、特定用途的適用性和不侵權的保證。 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE軟體.