Node.js proxy hecho simple. Configure el middleware proxy con facilidad para Connect, Express, Next.js y muchos más.
Impulsado por el popular NodeJitsu http-proxy .
Esta página muestra documentación para la versión v3.xx (notas de versión)
Consulte Migration.md para obtener detalles sobre cómo migrar de v2.xx a v3.xx
Si está buscando documentación anterior. Ir a:
Solicitudes de proxy /api a http://www.example.org
Consejo: Establezca la opción changeOrigin en true para sitios virtuales alojados basados en nombres.
// typescript
import * as express from 'express' ;
import type { Request , Response , NextFunction } from 'express' ;
import { createProxyMiddleware } from 'http-proxy-middleware' ;
import type { Filter , Options , RequestHandler } from 'http-proxy-middleware' ;
const app = express ( ) ;
const proxyMiddleware = createProxyMiddleware < Request , Response > ( {
target : 'http://www.example.org/api' ,
changeOrigin : true ,
} ) ;
app . use ( '/api' , proxyMiddleware ) ;
app . listen ( 3000 ) ;
// proxy and keep the same base path "/api"
// http://127.0.0.1:3000/api/foo/bar -> http://www.example.org/api/foo/bar Se pueden usar todas las opciones http-proxy , junto con algunas opciones adicionales http-proxy-middleware .
pathFilter (String, [] String, Glob, [] Glob, Función)pathRewrite (objeto/función)router (objeto/función)plugins (matriz)ejectPlugins (boolean) predeterminado: falselogger (objeto)http-proxyhttp-proxynpm install --save-dev http-proxy-middleware Cree y configure un middleware proxy con: createProxyMiddleware(config) .
const { createProxyMiddleware } = require ( 'http-proxy-middleware' ) ;
const apiProxy = createProxyMiddleware ( {
target : 'http://www.example.org' ,
changeOrigin : true ,
} ) ;
// 'apiProxy' is now ready to be used as middleware in a server.Opciones.Target : Target Host to Proxy a. (Protocolo + host)
opciones.changeorigin : para sitios alojados virtuales
Consulte la lista completa de opciones de configuración http-proxy-middleware
Un ejemplo con el servidor express .
// include dependencies
const express = require ( 'express' ) ;
const { createProxyMiddleware } = require ( 'http-proxy-middleware' ) ;
const app = express ( ) ;
// create the proxy
/** @type {import('http-proxy-middleware/dist/types').RequestHandler<express.Request, express.Response>} */
const exampleProxy = createProxyMiddleware ( {
target : 'http://www.example.org/api' , // target host with the same base path
changeOrigin : true , // needed for virtual hosted sites
} ) ;
// mount `exampleProxy` in web server
app . use ( '/api' , exampleProxy ) ;
app . listen ( 3000 ) ; Si desea utilizar el parámetro path app.use del servidor para que coincida con las solicitudes. Use la opción pathFilter para incluir/excluir las solicitudes que desea proxy.
app . use (
createProxyMiddleware ( {
target : 'http://www.example.org/api' ,
changeOrigin : true ,
pathFilter : '/api/proxy-only-this-path' ,
} ) ,
) ; app.use la documentación:
Opciones http-proxy-middleware:
pathFilter (String, [] String, Glob, [] Glob, Función) Estrecho hacia abajo que las solicitudes deben estar representadas. La path utilizada para el filtrado es el nombre de ruta request.url . En Express, esta es la path relativa al punto de montaje del proxy.
Mataje de la ruta
createProxyMiddleware({...}) - coincide con cualquier ruta, todas las solicitudes se proxen cuando pathFilter no esté configurada.createProxyMiddleware({ pathFilter: '/api', ...}) - coincide con las rutas que comienzan con /apicoincidencia de rutas múltiples
createProxyMiddleware({ pathFilter: ['/api', '/ajax', '/someotherpath'], ...})Matricante de la ruta de los comodines
Para el control de grano fino, puede usar la coincidencia de comodines. Micromatch realiza la coincidencia del patrón del globo. Visite Micromatch o Glob para más ejemplos de globas.
createProxyMiddleware({ pathFilter: '**', ...}) coincide con cualquier ruta, todas las solicitudes se representarán.createProxyMiddleware({ pathFilter: '**/*.html', ...}) coincide con cualquier ruta que termine con .htmlcreateProxyMiddleware({ pathFilter: '/*.html', ...}) coincide con las rutas directamente bajo ruta-absolutecreateProxyMiddleware({ pathFilter: '/api/**/*.html', ...}) Las solicitudes coinciden con .html en la ruta de /apicreateProxyMiddleware({ pathFilter: ['/api/**', '/ajax/**'], ...}) Combine múltiples patronescreateProxyMiddleware({ pathFilter: ['/api/**', '!**/bad.json'], ...}) ExclusiónNota : En la coincidencia de rutas múltiples, no puede usar rutas de cadena y rutas comodín.
coincidencia personalizada
Para el control completo, puede proporcionar una función personalizada para determinar qué solicitudes deben ser proxizadas o no.
/**
* @return {Boolean}
*/
const pathFilter = function ( path , req ) {
return path . match ( '^/api' ) && req . method === 'GET' ;
} ;
const apiProxy = createProxyMiddleware ( {
target : 'http://www.example.org' ,
pathFilter : pathFilter ,
} ) ;pathRewrite (objeto/función)Reescribir la ruta de URL de Target. Las teclas de objeto se utilizarán como regexp para que coincidan con las rutas.
// rewrite path
pathRewrite: { '^/old/api' : '/new/api' }
// remove path
pathRewrite: { '^/remove/api' : '' }
// add base path
pathRewrite: { '^/' : '/basepath/' }
// custom rewriting
pathRewrite: function ( path , req ) { return path . replace ( '/api' , '/base/api' ) }
// custom rewriting, returning Promise
pathRewrite: async function ( path , req ) {
const should_add_something = await httpRequestToDecideSomething ( path ) ;
if ( should_add_something ) path += "something" ;
return path ;
}router (objeto/función) option.target re-Target.Target para solicitudes específicas.
// Use `host` and/or `path` to match requests. First match will be used.
// The order of the configuration matters.
router: {
'integration.localhost:3000' : 'http://127.0.0.1:8001' , // host only
'staging.localhost:3000' : 'http://127.0.0.1:8002' , // host only
'localhost:3000/api' : 'http://127.0.0.1:8003' , // host + path
'/rest' : 'http://127.0.0.1:8004' // path only
}
// Custom router function (string target)
router: function ( req ) {
return 'http://127.0.0.1:8004' ;
}
// Custom router function (target object)
router: function ( req ) {
return {
protocol : 'https:' , // The : is required
host : '127.0.0.1' ,
port : 8004
} ;
}
// Asynchronous router function which returns promise
router: async function ( req ) {
const url = await doSomeIO ( ) ;
return url ;
}plugins (matriz) const simpleRequestLogger = ( proxyServer , options ) => {
proxyServer . on ( 'proxyReq' , ( proxyReq , req , res ) => {
console . log ( `[HPM] [ ${ req . method } ] ${ req . url } ` ) ; // outputs: [HPM] GET /users
} ) ;
} ,
const config = {
target : `http://example.org` ,
changeOrigin : true ,
plugins : [ simpleRequestLogger ] ,
} ;ejectPlugins (boolean) predeterminado: false Si no está satisfecho con los complementos preconfigurados, puede expulsarlos configurando ejectPlugins: true .
Nota: Registre sus propios manejadores de error para evitar que el servidor se bloquee.
// eject default plugins and manually add them back
const {
debugProxyErrorsPlugin , // subscribe to proxy errors to prevent server from crashing
loggerPlugin , // log proxy events to a logger (ie. console)
errorResponsePlugin , // return 5xx response on proxy error
proxyEventsPlugin , // implements the "on:" option
} = require ( 'http-proxy-middleware' ) ;
createProxyMiddleware ( {
target : `http://example.org` ,
changeOrigin : true ,
ejectPlugins : true ,
plugins : [ debugProxyErrorsPlugin , loggerPlugin , errorResponsePlugin , proxyEventsPlugin ] ,
} ) ;logger (objeto) Configure un registrador para obtener información de HTTP-Proxy-Middleware: IE. console , winston , pino , bunyan , log4js , etc ...
Solo info , warn , error se usan internamente para la compatibilidad en diferentes registradores.
Si usa winston , asegúrese de habilitar la interpolación: https://github.com/winstonjs/winston#string-interpolation
Consulte también Recetas de Logger (Recetas/Logger.MD) para obtener más detalles.
createProxyMiddleware ( {
logger : console ,
} ) ; http-proxy Suscríbase a los eventos HTTP-Proxy con la opción on :
createProxyMiddleware ( {
target : 'http://www.example.org' ,
on : {
proxyReq : ( proxyReq , req , res ) => {
/* handle proxyReq */
} ,
proxyRes : ( proxyRes , req , res ) => {
/* handle proxyRes */
} ,
error : ( err , req , res ) => {
/* handle error */
} ,
} ,
} ) ; Opción.on.error : función, suscribirse al evento error de HTTP-Proxy para el manejo de errores personalizados.
function onError ( err , req , res , target ) {
res . writeHead ( 500 , {
'Content-Type' : 'text/plain' ,
} ) ;
res . end ( 'Something went wrong. And we are reporting a custom error message.' ) ;
} Opción.on.proxyres : función, suscribirse al evento proxyRes de http-proxy.
function onProxyRes ( proxyRes , req , res ) {
proxyRes . headers [ 'x-added' ] = 'foobar' ; // add new header to response
delete proxyRes . headers [ 'x-removed' ] ; // remove header from response
} opción.on.proxyreq : función, suscríbase al evento proxyReq de http-proxy.
function onProxyReq ( proxyReq , req , res ) {
// add custom header to request
proxyReq . setHeader ( 'x-added' , 'foobar' ) ;
// or log the req
} opción.on.proxyreqws : función, suscribirse al evento proxyReqWs de http-proxy.
function onProxyReqWs ( proxyReq , req , socket , options , head ) {
// add custom header
proxyReq . setHeader ( 'X-Special-Proxy-Header' , 'foobar' ) ;
} opción.on.open : función, suscribirse al evento open de HTTP-Proxy.
function onOpen ( proxySocket ) {
// listen for messages coming FROM the target here
proxySocket . on ( 'data' , hybridParseAndLogMessage ) ;
} Opción.on.close : función, suscribirse al evento close de HTTP-Proxy.
function onClose ( res , socket , head ) {
// view disconnected websocket connections
console . log ( 'Client disconnected' ) ;
} http-proxyLas siguientes opciones son proporcionadas por la biblioteca HTTP-Proxy subyacente.
opción. Target : la cadena de URL se analizará con el módulo URL
opción. Forward : la cadena de URL se analizará con el módulo URL
opción. AGENT : Objeto que se pasará a HTTP (S) .Request (consulte los objetos del agente HTTPS de nodo y los objetos del agente HTTP)
opción.ssl : objeto que se pasará a https.createServer ()
opción.ws : verdadero/falso: si desea proxy WebSockets
opción.xfwd : verdadero/falso, agrega encabezados X-Forward
opción. Secure : Verdadero/Falso, si desea verificar los certificaciones SSL
opción.toproxy : verdadero/falso, pasa la URL absoluta como la path (útil para poder a los proxies)
opción
opción
opción. Localaddress : cadena de interfaz local para unir para conexiones salientes
opción
opción
Opción. Auth : autenticación básica es decir 'Usuario: contraseña' para calcular un encabezado de autorización.
opción. Hostrewrite : Reescribe el nombre de host de ubicación en (301/302/307/308) redireccionamientos.
Opción. AutoreWrite : Reescribe el host/puerto de ubicación en (301/302/307/308) redireccionamientos basados en el host/puerto solicitado. Predeterminado: falso.
Opción. Protocolrewrite : reescribe el protocolo de ubicación en (301/302/307/308) redirige a 'http' o 'https'. Valor predeterminado: NULL.
opción.cookiedomainrewrite : reescribe el dominio de encabezados set-cookie . Valores posibles:
false (predeterminado): deshabilitar la reescritura de cookies
Cadena: nuevo dominio, por ejemplo cookieDomainRewrite: "new.domain" . Para eliminar el dominio, use cookieDomainRewrite: "" .
Objeto: mapeo de dominios a nuevos dominios, use "*" para que coincida con todos los dominios.
Por ejemplo, mantenga un dominio sin cambios, reescribe un dominio y elimine otros dominios:
cookieDomainRewrite: {
"unchanged.domain" : " unchanged.domain " ,
"old.domain" : " new.domain " ,
"*" : " "
} opción set-cookie Valores posibles:
false (predeterminado): deshabilitar la reescritura de cookies
Cadena: nueva ruta, por ejemplo cookiePathRewrite: "/newPath/" . Para eliminar la ruta, use cookiePathRewrite: "" . Para establecer la ruta de la raíz, use cookiePathRewrite: "/" .
Objeto: mapeo de rutas a nuevas rutas, use "*" para que coincida con todas las rutas. Por ejemplo, para mantener una ruta sin cambios, reescribe una ruta y elimine otras rutas:
cookiePathRewrite: {
"/unchanged.path/" : " /unchanged.path/ " ,
"/old.path/" : " /new.path/ " ,
"*" : " "
} Opción. Headers : Objeto, agrega encabezados de solicitud. (Ejemplo: {host:'www.example.org'} )
Opción. ProxyTimeOut : Tiempo de espera (en milis) Cuando el proxy no recibe respuesta del objetivo
opción. Tiempo de tiempo : Tiempo de espera (en milis) para solicitudes entrantes
opción
Opción. SelfHandlerAponse True/False, si se establece en verdadero, no se llama a ninguno de los pases de webouts en curso y es su responsabilidad devolver adecuadamente la respuesta escuchando y actuando en el evento proxyRes
opción.buffer : flujo de datos para enviar como el cuerpo de solicitud. Tal vez tenga algún middleware que consuma el flujo de solicitudes antes de proxizarlo en, por ejemplo, si lee el cuerpo de una solicitud en un campo llamado 'req.rawbody', podría restringir este campo en la opción de búfer:
'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://127.0.0.1:4003/' ,
buffer : streamify ( req . rawBody ) ,
} ,
next ,
) ;
} ; // verbose api
createProxyMiddleware ( { pathFilter : '/' , target : 'http://echo.websocket.org' , ws : true } ) ; En los ejemplos de WebSocket anteriores, HTTP-Proxy-Middleware se basa en una solicitud HTTP inicial para escuchar el evento upgrade HTTP. Si necesita proxy WebSockets sin la solicitud HTTP inicial, puede suscribirse al evento upgrade HTTP del servidor manualmente.
const wsProxy = createProxyMiddleware ( { target : 'ws://echo.websocket.org' , changeOrigin : true } ) ;
const app = express ( ) ;
app . use ( wsProxy ) ;
const server = app . listen ( 3000 ) ;
server . on ( 'upgrade' , wsProxy . upgrade ) ; // <-- subscribe to http 'upgrade' Intercepts Solicitudes de aguas abajo definiendo onProxyReq en createProxyMiddleware .
Actualmente, el único interceptor de solicitud preproviado es fixRequestBody , que se utiliza para corregir solicitudes de publicación proxias cuando bodyParser se aplica antes de este middleware.
Ejemplo:
const { createProxyMiddleware , fixRequestBody } = require ( 'http-proxy-middleware' ) ;
const proxy = createProxyMiddleware ( {
/**
* Fix bodyParser
**/
on : {
proxyReq : fixRequestBody ,
} ,
} ) ; Interceptar respuestas desde aguas arriba con responseInterceptor . (Asegúrese de configurar selfHandleResponse: true )
Las respuestas que se compriman con brotli , gzip y deflate se descomprimirán automáticamente. La respuesta se devolverá como buffer (documentos) que puede manipular.
Con buffer , la manipulación de la respuesta no se limita a las respuestas de texto (HTML/CSS/JS, etc ...); La manipulación de la imagen también será posible. (ejemplo)
Nota: responseInterceptor deshabilita la transmisión de la respuesta de Target.
Ejemplo:
const { createProxyMiddleware , responseInterceptor } = require ( 'http-proxy-middleware' ) ;
const proxy = createProxyMiddleware ( {
/**
* IMPORTANT: avoid res.end being called automatically
**/
selfHandleResponse : true , // res.end() will be called internally by responseInterceptor()
/**
* Intercept response and replace 'Hello' with 'Goodbye'
**/
on : {
proxyRes : responseInterceptor ( async ( responseBuffer , proxyRes , req , res ) => {
const response = responseBuffer . toString ( 'utf8' ) ; // convert buffer to string
return response . replace ( 'Hello' , 'Goodbye' ) ; // manipulate response and return the result
} ) ,
} ,
} ) ;Consulte las recetas de intercepción para obtener más ejemplos.
Node.js 17+ ya no prefiere IPv4 a través de IPv6 para las búsquedas DNS. Por ejemplo, no está garantizado que localhost se resolverá a 127.0.0.1 , bien, también podría ser ::1 (o alguna otra dirección IP).
Si su servidor de destino solo acepta conexiones IPv4, intentar proxy a localhost fallará si se resuelve a ::1 (IPv6).
Formas de resolverlo:
target: "http://localhost" para target: "http://127.0.0.1" (IPv4).node : node index.js --dns-result-order=ipv4first . (No recomendado).Nota: Hay algo llamado Happy Eyeballs que significa conectarse con IPv4 e IPv6 en paralelo, que Node.js no tiene, pero explica por qué, por ejemplo,
curlpuede conectarse.
Configure la variable de entorno de DEBUG Activar el registro de depuración.
Vea el proyecto debug para obtener más opciones.
DEBUG=http-proxy-middleware * node server.js
$ http-proxy-middleware proxy created +0ms
$ http-proxy-middleware proxying request to target: ' http://www.example.org ' +359msVer y jugar con ejemplos de trabajo.
Ver las recetas para casos de uso comunes.
http-proxy-middleware es compatible con los siguientes servidores:
Las implementaciones de muestra se pueden encontrar en las recetas del servidor.
Ejecute la suite de prueba:
# install dependencies
$ yarn
# linting
$ yarn lint
$ yarn lint:fix
# building (compile typescript to js)
$ yarn build
# unit tests
$ yarn test
# code coverage
$ yarn cover
# check spelling mistakes
$ yarn spellcheckLa licencia del MIT (MIT)
Copyright (c) 2015-2024 Steven Chim