Как вернуться к клиенту в onProxyReq http-прокси-промежуточного программного обеспечения

#node.js #http-proxy-middleware

Вопрос:

Я пытаюсь создать обратный прокси-сервер с помощью express и http-proxy-middleware@2.0.1 с некоторой встроенной проверкой. Надеюсь, что в функции onProxyReq я смогу выполнить проверку, и если она завершится неудачей, я верну ошибку вызывающему абоненту вместо продолжения прокси-запроса.

Похоже, что если я немедленно отправлю 404 с «Недействительным», то он будет работать так, как ожидалось. Если при выполнении операции проверки возникает какая-либо задержка (смоделированная здесь с помощью функции setTimeout ()), то возникает ошибка «Не удается установить заголовки после их отправки клиенту». Есть ли способ заставить onProxyReq «подождать», пока моя проверка не завершится, и я смогу решить, нужно ли мне отвечать клиенту с ошибкой или продолжать использовать прокси-сервер.

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

function onProxyReq(proxyReq, req, res) {
    // Some validation

    // ** This causes the error "Cannot set headers after they are sent to the client"
    // setTimeout(()=>{
    //     res.status(404).send('Invalid')
    // }, 500)
    
    // ** This returns "Invalid" to the client as expected
    return res.status(404).send('Invalid')
}

// proxy middleware options
const options = {
  target: 'https://google.com',
  changeOrigin: true,
  logLevel: 'debug',
  onProxyReq,
};

const testProxy = createProxyMiddleware(options);
const app = express();

app.use('/', testProxy);


app.listen(3000);
 

Ответ №1:

Я сталкиваюсь с аналогичной ситуацией. Я прочитал код в модуле npm node-proxy (который используется промежуточным программным обеспечением http-прокси). Соответствующая строка, в которой вызывается событие proxyReq, находится здесь. В событии onProxyReq невозможно отменить или отложить прокси-запрос.

Для меня решение заключается в вставке моего собственного промежуточного ПО перед промежуточным ПО прокси-сервера. Адаптация вашего примера кода в соответствии с этим шаблоном приведет к чему-то, что выглядит следующим образом:

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

function customValidation(req, res, next) {
    setTimeout(()=>{
        if (validationSucceeds) {
             next(); //forward request through to proxy middleware
        } else {
             res.status(404).send('Invalid');
        }
    }, 500)
};

// proxy middleware options
const options = {
  target: 'https://google.com',
  changeOrigin: true,
  logLevel: 'debug'
};

const testProxy = createProxyMiddleware(options);
const app = express();

app.use('/', [customValidation, testProxy]);

app.listen(3000);
 

Комментарии:

1. На самом деле я закончил тем, что сделал это с помощью своего собственного промежуточного программного обеспечения, чтобы выполнить проверки и установить логическое значение для объекта req, а затем внутри функции onProxyReq, если логическое значение равно false, я выполняю вызов res.status(404).send («ошибка msg»), и, похоже, это работает.

2. Приятно, что у вас очень похожий подход. Единственное отличие от моего выше заключается в том, что промежуточное программное обеспечение прокси-сервера вообще не вызывается, если проверка не проходит успешно.

3. @MarkGlasgow Я хочу получить доступ к своему req.body , прежде чем отправлять на свой прокси-сервер, и я попробовал ваш метод. Но внутри моего промежуточного req.body программного обеспечения не определено. Можете ли вы подсказать, почему и что еще я могу сделать, чтобы достичь того, чего я хочу ? Спасибо.