Node.js Proxying dibuat sederhana. Konfigurasikan proxy middleware dengan mudah untuk Connect, Express, Next.js dan banyak lagi.
Didukung oleh NodeJitsu http-proxy yang populer.
Halaman ini menampilkan dokumentasi untuk versi v3.xx (catatan rilis)
Lihat Migration.md untuk detail tentang cara bermigrasi dari v2.xx ke v3.xx
Jika Anda mencari dokumentasi yang lebih lama. Pergi ke:
Permintaan proxy /api ke http://www.example.org
Kiat: Atur opsi changeOrigin ke true untuk situs host virtual berbasis nama.
// 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 Semua opsi http-proxy dapat digunakan, bersama dengan beberapa opsi http-proxy-middleware tambahan.
pathFilter (string, [] string, glob, [] glob, fungsi)pathRewrite (objek/fungsi)router (objek/fungsi)plugins (array)ejectPlugins (boolean) default: falselogger (objek)http-proxyhttp-proxynpm install --save-dev http-proxy-middleware Buat dan konfigurasikan middleware proxy dengan: 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.Options.target : Target host ke proxy ke. (Protokol + Host)
Options.changeorigin : untuk situs virtual yang di -host
Lihat Daftar Lengkap Opsi Konfigurasi http-proxy-middleware
Contoh dengan server 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 ) ; Jika Anda ingin menggunakan parameter path app.use server. Gunakan parameter untuk mencocokkan permintaan. Gunakan opsi pathFilter untuk memasukkan/mengecualikan permintaan lebih lanjut yang ingin Anda proxy.
app . use (
createProxyMiddleware ( {
target : 'http://www.example.org/api' ,
changeOrigin : true ,
pathFilter : '/api/proxy-only-this-path' ,
} ) ,
) ; Dokumentasi app.use :
Opsi HTTP-Proxy-Middleware:
pathFilter (string, [] string, glob, [] glob, fungsi) Persempit permintaan mana yang harus diproksi. path yang digunakan untuk memfilter adalah request.url pathname. Dalam Express, ini adalah path relatif terhadap mount-point proxy.
pencocokan jalur
createProxyMiddleware({...}) - Cocokkan jalur apa pun, semua permintaan akan diproksi ketika pathFilter tidak dikonfigurasi.createProxyMiddleware({ pathFilter: '/api', ...}) - cocok dengan jalur yang dimulai dengan /apiPencocokan beberapa jalur
createProxyMiddleware({ pathFilter: ['/api', '/ajax', '/someotherpath'], ...})Pencocokan jalur wildcard
Untuk kontrol berbutir halus, Anda dapat menggunakan pencocokan wildcard. Pencocokan pola glob dilakukan oleh Micromatch . Kunjungi Micromatch atau Glob untuk lebih banyak contoh globbing.
createProxyMiddleware({ pathFilter: '**', ...}) cocok dengan jalur apa pun, semua permintaan akan diproksi.createProxyMiddleware({ pathFilter: '**/*.html', ...}) cocok dengan jalur apa pun yang diakhiri dengan .htmlcreateProxyMiddleware({ pathFilter: '/*.html', ...}) cocok dengan jalur langsung di bawah jalur-absolutecreateProxyMiddleware({ pathFilter: '/api/**/*.html', ...}) cocok dengan permintaan yang diakhiri dengan .html di jalur /apicreateProxyMiddleware({ pathFilter: ['/api/**', '/ajax/**'], ...}) Gabungkan beberapa polacreateProxyMiddleware({ pathFilter: ['/api/**', '!**/bad.json'], ...}) pengecualianCatatan : Di beberapa pencocokan jalur, Anda tidak dapat menggunakan jalur string dan jalur wildcard bersama -sama.
pencocokan khusus
Untuk kontrol penuh, Anda dapat memberikan fungsi khusus untuk menentukan permintaan mana yang harus diproksi atau tidak.
/**
* @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 (objek/fungsi)Tulis ulang jalur URL Target. Object-Keys akan digunakan sebagai RegExp untuk mencocokkan jalur.
// 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 (objek/fungsi) option.target target ulang.target untuk permintaan tertentu.
// 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 (array) 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) default: false Jika Anda tidak puas dengan plugin yang telah dikonfigurasi sebelumnya, Anda dapat mengeluarkannya dengan mengonfigurasi ejectPlugins: true .
Catatan: Daftarkan penangan kesalahan Anda sendiri untuk mencegah server mogok.
// 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 (objek) Konfigurasikan logger ke informasi output dari http-proxy-middleware: yaitu. console , winston , pino , bunyan , log4js , dll ...
Hanya info , warn , error yang digunakan secara internal untuk kompatibilitas di berbagai penebang.
Jika Anda menggunakan winston , pastikan untuk mengaktifkan interpolasi: https://github.com/winstonjs/winston#string-interpolation
Lihat juga Resep Logger (Resep/Logger.MD) untuk lebih jelasnya.
createProxyMiddleware ( {
logger : console ,
} ) ; http-proxy Berlangganan acara HTTP-Proxy dengan opsi 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 */
} ,
} ,
} ) ; Option.on.error : Fungsi, berlangganan acara error HTTP-Proxy untuk penanganan kesalahan khusus.
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.' ) ;
} Option.on.proxyres : Fungsi, berlangganan acara proxyRes 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
} Option.on.proxyreq : Fungsi, berlangganan acara proxyReq HTTP-Proxy.
function onProxyReq ( proxyReq , req , res ) {
// add custom header to request
proxyReq . setHeader ( 'x-added' , 'foobar' ) ;
// or log the req
} option.on.proxyreqws : Fungsi, berlangganan acara proxyReqWs HTTP-Proxy.
function onProxyReqWs ( proxyReq , req , socket , options , head ) {
// add custom header
proxyReq . setHeader ( 'X-Special-Proxy-Header' , 'foobar' ) ;
} option.on.open : Fungsi, berlangganan acara open HTTP-Proxy.
function onOpen ( proxySocket ) {
// listen for messages coming FROM the target here
proxySocket . on ( 'data' , hybridParseAndLogMessage ) ;
} Option.on.close : Fungsi, berlangganan acara close HTTP-Proxy.
function onClose ( res , socket , head ) {
// view disconnected websocket connections
console . log ( 'Client disconnected' ) ;
} http-proxyOpsi berikut disediakan oleh perpustakaan HTTP-Proxy yang mendasarinya.
opsi.target : string URL untuk diuraikan dengan modul URL
Option.forward : string URL untuk diuraikan dengan modul URL
opsi.agent : objek yang akan diteruskan ke http.
Option.ssl : Objek yang akan diteruskan ke https.createServer ()
opsi.ws : true/false: Jika Anda ingin proxy websockets
opsi.xfwd : Benar/Salah, menambahkan header X-Forward
opsi.secure : true/false, jika Anda ingin memverifikasi sertifikat SSL
Option.toproxy : Benar/Salah, melewati URL absolut sebagai path (berguna untuk proksi ke proxy)
option.prependpath : true/false, default: true - Tentukan apakah Anda ingin menyiapkan jalur target ke jalur proxy
Option.ignoRePath : Benar / Salah, Default: Salah - Tentukan apakah Anda ingin mengabaikan jalur proxy dari permintaan yang masuk (Catatan: Anda harus menambahkan / secara manual jika diperlukan).
Option.LocalAddress : String antarmuka lokal untuk mengikat koneksi keluar
Option.changeorigin : Benar/Salah, Default: Salah - Mengubah asal header host ke URL target
option.preserveaderKeyCase : true/false, default: false - Tentukan apakah Anda ingin menyimpan huruf huruf respons header kunci
Option.Auth : Otentikasi Dasar yaitu 'Pengguna: Kata Sandi' untuk menghitung header otorisasi.
Option.hostrewrite : Menulis ulang nama host lokasi pada (301/302/307/308) Redirects.
Option.AutoRewrite : Menulis ulang host/port lokasi pada (301/302/307/308) mengarahkan ulang berdasarkan host/port yang diminta. Default: Salah.
Option.protocolrewrite : Menulis ulang protokol lokasi pada (301/302/307/308) mengarahkan kembali ke 'http' atau 'https'. Default: NULL.
Option.cookiedomainrewrite : Menulis ulang domain header set-cookie . Nilai yang mungkin:
false (default): Nonaktifkan penulisan ulang cookie
String: domain baru, misalnya cookieDomainRewrite: "new.domain" . Untuk menghapus domain, gunakan cookieDomainRewrite: "" .
Objek: Pemetaan domain ke domain baru, gunakan "*" untuk mencocokkan semua domain.
Misalnya, jaga satu domain tidak berubah, tulis ulang domain satu dan hapus domain lainnya:
cookieDomainRewrite: {
"unchanged.domain" : " unchanged.domain " ,
"old.domain" : " new.domain " ,
"*" : " "
} Option.CookIePathRewrite : Menulis ulang jalur header set-cookie . Nilai yang mungkin:
false (default): Nonaktifkan penulisan ulang cookie
String: Path baru, misalnya cookiePathRewrite: "/newPath/" . Untuk menghapus jalan setapak, gunakan cookiePathRewrite: "" . Untuk mengatur jalur ke root menggunakan cookiePathRewrite: "/" .
Objek: Pemetaan jalur ke jalur baru, gunakan "*" untuk mencocokkan semua jalur. Misalnya, untuk menjaga satu jalur tidak berubah, tulis ulang satu jalur dan menghapus jalur lain:
cookiePathRewrite: {
"/unchanged.path/" : " /unchanged.path/ " ,
"/old.path/" : " /new.path/ " ,
"*" : " "
} Option.Headers : Objek, menambahkan header permintaan. (Contoh: {host:'www.example.org'} )
opsi.proxytimeout : timeout (dalam millis) saat proxy tidak menerima tanggapan dari target
Option.Timeout : Timeout (di Millis) untuk permintaan yang masuk
opsi.followredirects : true/false, default: false - Tentukan apakah Anda ingin mengikuti pengalihan
opsi.SelfHandLereSponse True/False, jika diatur ke true, tidak ada operan webouting yang dipanggil dan itu adalah tanggung jawab Anda untuk mengembalikan respons dengan tepat dengan mendengarkan dan bertindak di acara proxyRes
Option.Buffer : Aliran data untuk dikirim sebagai badan permintaan. Mungkin Anda memiliki beberapa middleware yang mengkonsumsi aliran permintaan sebelum memberikannya di EG jika Anda membaca tubuh permintaan ke bidang yang disebut 'req.rawbody' Anda dapat menahan bidang ini di opsi buffer:
'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 } ) ; Dalam contoh Websocket sebelumnya, http-proxy-middleware bergantung pada permintaan HTTP awal untuk mendengarkan acara upgrade HTTP. Jika Anda perlu proxy websockets tanpa permintaan HTTP awal, Anda dapat berlangganan acara upgrade HTTP server secara manual.
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' Pencegatan permintaan dari hilir dengan mendefinisikan onProxyReq di createProxyMiddleware .
Saat ini satu-satunya pencegat permintaan pra-disediakan adalah fixRequestBody , yang digunakan untuk memperbaiki permintaan pos proksi ketika bodyParser diterapkan sebelum middleware ini.
Contoh:
const { createProxyMiddleware , fixRequestBody } = require ( 'http-proxy-middleware' ) ;
const proxy = createProxyMiddleware ( {
/**
* Fix bodyParser
**/
on : {
proxyReq : fixRequestBody ,
} ,
} ) ; Tanggapan mencegat dari hulu dengan responseInterceptor . (Pastikan untuk mengatur selfHandleResponse: true )
Respons yang dikompresi dengan brotli , gzip dan deflate akan didekompresi secara otomatis. Responsnya akan dikembalikan sebagai buffer (dokumen) yang dapat Anda manipulasi.
Dengan buffer , manipulasi respons tidak terbatas pada respons teks (HTML/CSS/JS, dll ...); Manipulasi gambar juga akan dimungkinkan. (contoh)
Catatan: responseInterceptor menonaktifkan streaming respons Target.
Contoh:
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
} ) ,
} ,
} ) ;Lihat resep intersepsi untuk lebih banyak contoh.
Node.js 17+ tidak lagi lebih suka IPv4 daripada IPv6 untuk pencarian DNS. Misalnya tidak dijamin bahwa localhost akan diselesaikan menjadi 127.0.0.1 - mungkin juga ::1 (atau alamat IP lainnya).
Jika server target Anda hanya menerima koneksi IPv4, mencoba untuk proxy ke localhost akan gagal jika diselesaikan ke ::1 (IPv6).
Cara untuk menyelesaikannya:
target: "http://localhost" ke target: "http://127.0.0.1" (ipv4).node : node index.js --dns-result-order=ipv4first . (Tidak direkomendasikan.)Catatan: Ada sesuatu yang disebut Happy Eyeballs yang berarti menghubungkan ke IPv4 dan IPv6 secara paralel, yang tidak dimiliki Node.js, tetapi menjelaskan mengapa misalnya
curldapat terhubung.
Konfigurasikan variabel lingkungan DEBUG memungkinkan pencatatan debug.
Lihat Proyek debug untuk lebih banyak opsi.
DEBUG=http-proxy-middleware * node server.js
$ http-proxy-middleware proxy created +0ms
$ http-proxy-middleware proxying request to target: ' http://www.example.org ' +359msLihat dan bermain -main dengan contoh yang berfungsi.
Lihat resep untuk kasus penggunaan umum.
http-proxy-middleware kompatibel dengan server berikut:
Implementasi sampel dapat ditemukan di resep server.
Jalankan test suite:
# 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 spellcheckLisensi MIT (MIT)
Hak Cipta (C) 2015-2024 Steven Chim