node.jsexpresshttp-proxy-middleware

How to build a nodejs(express) proxy using http-proxy-middleware?


I try to proxy all interfaces of http://A.com to http://B.com. And then I want to change the result of interface '/api/v2'. But what i do is not worked for the interface '/api/v2'. My logs in proxyRes don't run. Here is the code in my server.

const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');

const app = express();

app.use('/api/v2', createProxyMiddleware({
  target: 'http://B.com',
  changeOrigin: true,
  on: {
    proxyRes: (proxyRes, req, res) => {
      console.log('proxy res here =====');
      proxyRes.headers['x-added'] = 'foobar';
    }
  }
}));

app.use('/', createProxyMiddleware({ target: 'http://B.com', changeOrigin: true }));

// 启动服务器
const port = 3000;
app.listen(port, () => {
  console.log(`Server is running on port ${port}`);
});

Is there anything wrong with my code? Proxy A.com to B.com is worked. But it seems app.use('/api/v2', ......) is not worked at all. I want to change its response header and response data.

env


Solution

  • From the http-proxy events documentation, it should be option.onProxyRes.

    const express = require('express');
    const { createProxyMiddleware } = require('http-proxy-middleware');
    
    const app = express();
    
    app.use(
        '/api/v2',
        createProxyMiddleware({
            target: 'https://jsonplaceholder.typicode.com',
            pathRewrite: {
                '^/api/v2': '',
            },
            changeOrigin: true,
            onProxyRes: (proxyRes, req, res) => {
                console.log('proxy res here =====');
                proxyRes.headers['x-added'] = 'foobar';
            },
        }),
    );
    
    // 启动服务器
    const port = 3000;
    app.listen(port, () => {
        console.log(`Server is running on port ${port}`);
    });
    

    Test:

    ✗ curl -i --request GET http://localhost:3000/api/v2/todos/1
    HTTP/1.1 200 OK
    x-powered-by: Express
    date: Tue, 28 Nov 2023 08:48:31 GMT
    content-type: application/json; charset=utf-8
    content-length: 83
    connection: close
    report-to: {"group":"heroku-nel","max_age":3600,"endpoints":[{"url":"https://nel.heroku.com/reports?ts=1700986863&sid=e11707d5-02a7-43ef-b45e-2cf4d2036f7d&s=FwLcy2E2TneWtDma4sLiQRIGzoY%2FlU%2BGZ83naoahnso%3D"}]}
    reporting-endpoints: heroku-nel=https://nel.heroku.com/reports?ts=1700986863&sid=e11707d5-02a7-43ef-b45e-2cf4d2036f7d&s=FwLcy2E2TneWtDma4sLiQRIGzoY%2FlU%2BGZ83naoahnso%3D
    nel: {"report_to":"heroku-nel","max_age":3600,"success_fraction":0.005,"failure_fraction":0.05,"response_headers":["Via"]}
    x-ratelimit-limit: 1000
    x-ratelimit-remaining: 999
    x-ratelimit-reset: 1700986910
    vary: Origin, Accept-Encoding
    access-control-allow-credentials: true
    cache-control: max-age=43200
    pragma: no-cache
    expires: -1
    x-content-type-options: nosniff
    etag: W/"53-hfEnumeNh6YirfjyjaujcOPPT+s"
    via: 1.1 vegur
    cf-cache-status: HIT
    age: 691
    accept-ranges: bytes
    server: cloudflare
    cf-ray: 82d15a340e1a48c9-LHR
    alt-svc: h3=":443"; ma=86400
    x-added: foobar
    
    {
      "userId": 1,
      "id": 1,
      "title": "delectus aut autem",
      "completed": false
    }% 
    

    The x-added: foobar response header is added.