Ваш код выглядел нормально, поэтому мне было любопытно и попробовал его.
Хотя вы регистрируете несколько ошибок, вы не обрабатываете несколько случаев:
- Сервер возвращает тело без ответа (
cheerio
сгенерирует пустое HTML тело, когда это происходит) - Сервер возвращает ответ, который не был распакован (ваш код будет молча отбрасывать ответ)
Я внес несколько изменений в ваш код.
Изменить начальные параметры
let proxy = httpProxy.createProxyServer({
secure: false,
changeOrigin: true
});
- Не проверять сертификаты TLS
secure: false
- Отправить правильный заголовок
Host
changeOrigin: true
Удалите оператор if
и замените его троичным
const isCompressed = proxyRes.headers['content-encoding'] === 'gzip';
const decompressed = isCompressed ? await ungzip(buffer) : buffer;
Вы также можете удалить 2 await
на cheerio
, Cheerio не asyn c и не возвращает await
возможность.
Финальный код
Вот финальный код, который работает. Вы упомянули, что «похоже, что узел-http-прокси сильно умирает [...] в зависимости от того, сколько раз я запускал сервер». У меня не было таких проблем со стабильностью, поэтому ваши проблемы могут быть ie в другом месте, если это происходит (плохой баран?)
const cheerio = require('cheerio');
const http = require('http');
const httpProxy = require('http-proxy');
const { ungzip } = require('node-gzip');
const host = 'https://github.com';
let proxy = httpProxy.createProxyServer({
secure: false,
changeOrigin: true
});
let option = {
target: host,
selfHandleResponse: true
};
proxy.on('proxyRes', function (proxyRes, req, res) {
console.log(`Proxy response with status code: ${proxyRes.statusCode} to url ${req.url}`);
if (proxyRes.statusCode == 301) {
throw new Error('You should probably do something here, I think there may be an httpProxy option to handle redirects');
}
let body = [];
proxyRes.on('data', function (chunk) {
body.push(chunk);
});
proxyRes.on('end', async function () {
let buffer = Buffer.concat(body);
try {
let $ = null;
const isCompressed = proxyRes.headers['content-encoding'] === 'gzip';
const decompressed = isCompressed ? await ungzip(buffer) : buffer;
const scriptTag = '<script src="my-customjs.js"></script>';
$ = cheerio.load(decompressed.toString());
$('body').append(scriptTag);
res.end($.html());
} catch (e) {
console.log(e);
}
});
});
let server = http.createServer(function (req, res) {
proxy.web(req, res, option, function (e) {
console.log(e);
});
});
console.log("listening on port 5051");
server.listen(5051);