Node.js HTTP代理修改主体

我想要编程的Node.js http代理将能够修改响应正文。 到目前为止,

http = require('http'), httpProxy = require('http-proxy'); var proxy = httpProxy.createProxyServer(); http.createServer( function (req, res){ //here I want to change the body I guess proxy.web(req, res, { target: req.url }); }).listen(8013); 

我试图使用res.write() ,但它给了我一个错误“发送后无法设置标题”。 那么我不想改变头,我想改变身体。
我如何改变身体? 任何build议将不胜感激。

你得到这个错误是因为写入HTTP响应必然会改变标题; Content-Length必须正确。

我解决这个问题的方法是缓冲整个响应体,使用cheerioparsing和提琴,然后把结果发送给客户端。

在将请求交给http-proxy模块之前,我通过修补res.writeHeadres.writeres.end完成了这个任务。

 function requestHandler(req, res) { var writeHead = res.writeHead, write = res.write, end = res.end; res.writeHead = function(status, reason, headers) { if (res.headersSent) return req.socket.destroy(); // something went wrong; abort if (typeof reason == 'object') headers = reason; headers = headers || {}; res.headers = headers; if (headers['content-type'] && headers['content-type'].substr(0,9) == 'text/html') { // we should only fiddle with HTML responses delete headers['transfer-encoding']; // since we buffer the entire response, we'll send a proper Content-Length later with no Transfer-Encoding. var buf = new Buffer(); res.write = function(data, encoding) { if (Buffer.isBuffer(data)) buf = Buffer.concat([buf, data]); // append raw buffer else buf = Buffer.concat([buf, new Buffer(data, encoding)]); // append string with optional character encoding (default utf8) if (buf.length > 10 * 1024 * 1024) error('Document too large'); // sanity check: if the response is huge, bail. // ...we don't want to let someone bring down the server by filling up all our RAM. } res.end = function(data, encoding) { if (data) res.write(data, encoding); var $ = cheerio.load(buf.toString()); // This is where we can modify the response. For example, $('body').append('<p>Hi mom!</p>'); buf = new Buffer($.html()); // we have to convert back to a buffer so that we can get the *byte count* (rather than character count) of the body res.headers['content-type'] = 'text/html; charset=utf-8'; // JS always deals in UTF-8. res.headers['content-length'] = buf.length; // Finally, send the modified response out using the real `writeHead`/`end`: writeHead.call(res, status, res.headers); end.call(res, buf); } } else { writeHead.call(res, status, headers); // if it's not HTML, let the response go through normally } } proxy.web(req, res, { target: req.url }); function error(msg) { // utility function to report errors if (res.headersSent) end.call(res, msg); else { msg = new Buffer(msg); writeHead.call(res, 502, { 'Content-Type': 'text/plain', 'Content-Length': msg.length }); end.call(res, msg); } } }