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 及贡献者。
特此免费授予获得本软件和相关文档文件(“软件”)副本的任何人不受限制地使用本软件,包括但不限于使用、复制、修改、合并的权利、发布、分发、再许可和/或销售软件的副本,并允许向其提供软件的人员这样做,但须满足以下条件:
上述版权声明和本许可声明应包含在本软件的所有副本或主要部分中。
本软件按“原样”提供,不提供任何明示或暗示的保证,包括但不限于适销性、特定用途的适用性和不侵权的保证。在任何情况下,作者或版权持有者均不对因本软件或本软件中的使用或其他交易而产生或与之相关的任何索赔、损害或其他责任负责,无论是合同、侵权行为还是其他行为。软件。