使用Node HTTP Server发送新的请求响应

时间:2017-11-22 02:35:38

标签: node.js http-proxy

Stack Overflow社区,问候。我尝试使用Node HTTP Module为我的网站上的基本自动完成搜索应用传递请求对象上的新请求的响应(即使用Node作为代理,将转换和重定向请求服务器)。

流程主要是:

客户端浏览器 - 节点 - ElasticSearch - 节点 - 客户端浏览器

我开始时:

  • 使用http.createServer (function (req,res)

  • 收听请求
  • req 对象获取正文,并在http.request(options, function (newReqResponse)

  • 的新请求中使用它
  • newReqResponse 对象获取正文并将其发送回 res 对象上的客户端

问题是 newReqResponse 的内容总是过时的(最后一个类型字符后面的路径)。即:

  • 如果我输入" te",newReqResponse的内容对应于我只输入" t"。
  • 如果我输入" test",如果我输入" tes"那就相当于它。

等等。

我尝试使用Node.js流解决它,并使用文件系统模块写入和读取文件sync和async,但结果是一样的。这是整个代码图片的样本:

var http = require('http');
var fs = require('fs');

http.createServer(function (req, res) {
    var reqBody = '';
    var newReqResponseBody = "";
    req.on('data', function (chunk) {
        reqBody += chunk;
        fs.writeFile('reqbody.json', reqBody, function(err) {
        if (err) {
          throw err;
        }
      });
      var options = {
      hostname: '127.0.0.1',
      port: 9500,
      method: 'GET',
      path: '/_search',
      headers: { host: 'es',
        'content-length': Buffer.byteLength(reqBody),
        'content-type': 'application/json',
        accept: 'application/json' },
    };

      var newReq = http.request(options, function (newReqResponse) {


    newReqResponse.setEncoding("UTF-8");

    newReqResponse.on('data', function (ch) {
      newReqResponseBody += ch;
    });

    newReqResponse.on("end", function() {
      fs.writeFile("newReqResponseBody.json", newReqResponseBody, function(err) {
        if (err) {
          throw err;
        }
      });
    });
    });


newReq.on("error", function(err) {
      console.log(`problem with request: ${err.message}`);
      });
newReq.write(reqBody);
newReq.end();


    });

    req.on('end', function() {
    var responseBody = fs.readFileSync('newReqResponseBody.json', 'utf8');
console.log(responseBody);
res.end(responseBody);   
    });

}).listen(3000, '127.0.0.1');

是否有解决方法来处理http服务器中的请求和响应?如果没有,如果你给我任何指示如何解决这个问题,我将非常感激。

由于Node的计划用途相当基本,我更喜欢坚持使用核心模块,而不是必须从npm获取新模块,除非它是必要的。

提前致谢。

修改

我所要做的只是在res.end(responseBody)回调中拨打newReqResponse.on("end"),这对我来说完全违反直觉,但是......确实有效。

1 个答案:

答案 0 :(得分:1)

很高兴你解决了自己的问题。但是,我看到了改进的空间(不确定你是否是新手),特别是如果你正在传输数据。你可以用流做什么。

您可以看到我没有计算内容长度,根据HTTP规范要求您不要并且应该忽略(针对此特定情况),因为流以'Transfer-Encoding': 'chunked'标头的块传递数据。

const fs = require('fs');
const http = require('http');

const options = {
    hostname: '127.0.0.1',
    port: 9500,
    method: 'GET',
    path: '/_search',
    headers: {
        'Content-Type': 'application/json'
    }
};

http.createServer((req, res) => {
    req.pipe(fs.createWriteStream('reqBody.json'));

    let request = http.request(options, (newRes) => {
        newRes.pipe(res);
    });
    fs.createReadStream('reqBody.json').pipe(request);

    res.setHeader('Content-Type', 'application/json');

}).listen(3000, '127.0.0.1');

如果您不希望将来保存数据并且只想将req流传输到request,则可以更多地缩短此代码段。