README
This is an express proxy middleware. In addition to normal proxy forwarding function, it can also extend additional parameters, such as extending headers, extending URL parameters, and extending body parameters
install
npm i express-create-proxy
usage
const express = require('express')
const app = express()
const path = require('path')
const bodyParser = require('body-parser')
const { createProxy } = require('express-create-proxy')
const proxy = createProxy({
proxy: {
'^/api': {
target: 'http://localhost:3002',
pathRewrite: { // rewrite url reference to http-proxy-middleware
'^/api': '/api'
}
}
}
})
app.use(proxy)
app.listen(3000, () => {
console.log('start at 3000')
})
proxy config
const proxy = createProxy({
proxy: {
'^/api': {
target: 'http://localhost:3002',
pathRewrite: { // rewrite url reference to http-proxy-middleware
'^/api': '/api'
}
},
'^/another': {
target: 'http://xxxx.com'
}
}
})
// or proxy all
const proxy = createProxy({
proxy: 'http://localhost:3002'
})
requestOptions (addtional params data headers for every request)
const proxy = createProxy({
proxy: {
'^/api': {
target: 'http://localhost:3002',
pathRewrite: {
'^/api': '/api'
}
}
},
requestOptions: {
params: { // url search
a: 'a'
},
data: { // body data
b: 'b',
c: 'c',
file: { // post file (only when content-type: multipart/form-data)
path: 'xxxx.jpg'
}
},
headers: { // header
'someHeader': 'headerValue'
},
beforeRequest(req, res, options) {
// options is equal to requestOptions
console.log(options)
return {
params: {
// some url params
...(options.params || {})
},
data: {
// some body data
...(options.data || {})
},
headers: {
// some headers
...(options.headers || {})
}
}
},
onRequest (url, httpOptions, httpReq, req, res) { // when send http request
console.log(url) // request url
console.log(httpOptions) // request options
},
onResponse (httpRes, httpReq, res, req) { // http.ServerResponse, http.ClientRequest
},
}
})
modules
1. proxyRequest (req, res, url, options)
usage
const { proxyRequest } = require('express-create-proxy')
app.get('/api/test', (req, res) => {
const target = 'http://localhost:3002'
proxyRequest(req, res, target + req.originalUrl, {
params: {}, // aditional params
data: {}, // aditional data
headers: {}, // aditional headers
redirect: false, // is redirection supported
beforeRequest(req, res, options) {
return options
},
onResponse (httpRes, httpReq) { // http.ServerResponse, http.ClientRequest
},
})
})
// redirect
const { proxyRequest } = require('express-create-proxy')
app.get('/api/test', (req, res) => {
const target = 'http://localhost:3002'
proxyRequest(req, res, target + req.originalUrl, {
params: {}, // aditional params
data: {}, // aditional data
headers: {}, // aditional headers
redirect: true // is redirection supported
})
})
// custom responseData
const { proxyRequest } = require('express-create-proxy')
app.get('/api/json', (req, res) => {
const target = 'http://localhost:3002'
function responseCallback (resData) {
const data = {
...resData,
name: 'jack'
}
res.send(data)
}
proxyRequest(req, res, target + req.originalUrl, {
params: {}, // aditional params
data: {}, // aditional data
headers: {}, // aditional headers
redirect: true, // is redirection supported
}, responseCallback)
})
// stream download
const { proxyRequest } = require('express-create-proxy')
app.get('/api/download', (req, res) => {
const target = 'http://localhost:3002'
function responseCallback (resStream) {
res.set('Content-Disposition', 'attachment; filename="download.jpg"')
res.set('Content-Type', 'image/jpeg')
resStream.pipe(res)
}
proxyRequest(req, res, target + req.originalUrl, {
params: {}, // aditional params
data: {}, // aditional data
headers: {}, // aditional headers
redirect: true, // is redirection supported
responseType: 'stream'
}, responseCallback)
})
2. File
properties
- type: file's MIME type
- path: file's absolute path
- size: file size
- source: file stream (fs.createReadStream(file.path))
- filename: file's name defaults path.basename(file.path)
usage
const { proxyRequest, File } = require('express-create-proxy')
// req.get('content-type') must be multipart/form-data
// basic usage
app.post('/api/test', (req, res) => {
proxyRequest(req, res, req.baseUrl + req.url, {
params: {},
data: {
file: {
path: 'xxxx.jpg',
filename: 'xxx.jpg' // default value is require('path').basename(file.path),
type: 'image/jpeg' // default require('mime-types').lookup(file.path)
}
},
headers: {},
// beforeRequest(req, res, options) {
// return options
// }
})
})
// advanced usage
app.post('/api/test', (req, res) => {
proxyRequest(req, res, req.baseUrl + req.url, {
params: {},
data: {
file: new File('xxx.jpg', {
filename: 'xxx.jpg' // default value is require('path').basename(file.path),
type: 'image/jpeg' // default require('mime-types').lookup(file.path)
})
},
headers: {},
// beforeRequest(req, res, options) {
// return options
// }
})
})
3. FormData
properties
- form: instance of CombinedStream reference to combined-stream
- boundary: multipart/form-data boundary defaults uuidv4()
methods
- getContentType: return
multipart/form-data; boundary=${this.boundary}
- getContentLength: get form data's bytelength
- setBoundary(boundary: String): set boundary
- append(key, value): append data
- build(data: Object): build form Data
const { FormData, File } = require('express-create-proxy')
const formData = new FormData()
formData.build({
data1: 'data1',
data2: 'data2',
file: new File('xxxx.jpg'),
file1: {
path: 'xxxx.jpg'
}
})
// build equal to
// const data = {
// data1: 'data1',
// data2: 'data2',
// file: new File('xxxx.jpg'),
// file1: {
// path: 'xxxx.jpg'
// }
// }
// Object.keys(data).forEach(key => {
// formData.append(key, data[key])
// })
- pipe(src: writeStream, Duplex Transform, options: Object({hasTail: true | false}))
usage
const { FormData, request, File } = require('express-create-proxy')
const formData = new FormData()
// formData.setBoundary('xxxxxx') // set boundary defaults uuidv4()
formData.append('key', 'value')
formData.append('file1', new File(path.resolve(__dirname, '../test.txt')))
const httpReq = request('http://localhost:3003/file', {
method: 'post',
params: {},
headers: { // set header or use node clientRequest api httpReq.setHeader('content-type', formData.getContentType())
'content-type': formData.getContentType(),
}
})
httpReq.on('response', res => {
console.log(res.statusCode)
})
httpReq.on('error', e => {
console.log(e)
})
formData.pipe(httpReq, {hasTail: true}, () => { // if hasTail: false There is no ending separator (source code is `--${this.boundary}--\r\n`) defaults true
httpReq.setHeader('content-length', formData.getContentLength())
})