当前位置: 首页 > 知识库问答 >
问题:

如何全局使用节点http请求

严曜文
2023-03-14

我知道Javascript,但对NodeJS非常陌生。我希望在代码中的任何位置,即server.js之外的位置,重用HTTP请求。请看一看:

server.js


    var http = require('http');
    var mongodb = require('./db');
    var settings = require('./settings');
    var oauth = require('./oauth');

    //start mongodb connection
    mongodb.connect(function(error){
        if (error) console.error(error);
        else {
            //set db as mongodb client
            var db = mongodb.use();
            //start http server
            http.createServer(function(request,response){
                //set POST body
                request.body = '';
                request.on('error',function(error){
                    console.error(error);
                    response.statusCode = 404;
                    response.end();
                }).on('data',function(chunk){
                    request.body += chunk;
                }).on('end',function(){
                    //database and http server ready, start logic
                    //Now I want to "require" a file here, such as test.js and call "request.headers" to work
                });
            }).listen(settings.httpPort,function(){
                console.log('Server listening on '+settings.httpServer+':'+settings.httpPort);
            });
        }
    });


    console.log(request.headers);

共有1个答案

孙钱青
2023-03-14

如果我没有理解错的话,问题似乎是这样的:您希望在其他模块中访问异步函数的结果(HTTP请求)。但是,节点的require()是同步的;不存在异步require()。对此有几个解决方案,如果您了解JavaScript,这些方案都不会感到陌生。

最简单的解决方案是将server.js模块包装在一个接受回调的函数中。然后,一旦请求可用,就调用回调,如下所示:

// server.js
'use strict';

// ...

module.exports = function(callback) {

  // ...

  http.createServer((req, res) => {
    req.body = '';

    // Call end with error on error
    req.on('error', err => res.end(err));

    // Append chunks to body
    req.on('data', chunk => req.body += chunk);

    // Call callback here
    req.on('end', err => {
      // Call with error as first argument on error
      if (err) callback(err);
      // Call with request as second argument on success
      else callback(null, req);
    });

  }).listen(/*...*/);
  // ...
};

在test.js文件中:

// test.js
'use strict';

const server = require('./server');

// Do something with the request here.
server((err, req) => {
  if (err) console.error(err);
  else console.log(req.headers);
});

这种方法有一个问题。每次想要访问请求时,您的服务器功能都将重新运行一遍。如果您希望运行一次服务器,然后可以访问请求的次数不受限制,该怎么办?

考虑为此使用节点的events模块。在server.js文件中,可以导出EventEmitter实例而不是函数。在该模块中发出适当的事件,然后您可以在任何其他需要访问请求的模块中添加侦听器。server.js文件将如下所示:

// server.js
'use strict';

const EventEmitter = require('events');
const emitter = new EventEmitter();

// ...

http.createServer((req, res) => {
  req.body = '';
  req.on('error', err => res.end(err));
  req.on('data', chunk => req.body += chunk);

  // Emit events here:
  req.on('end', err => {
    // Emit 'error' event on error.
    if (err) emitter.emit('error', err);
    // Emit 'data' event on success.
    else emitter.emit('data', req);
  });
}).listen(/*...*/);

// ...

module.exports = emitter;

在test.js文件中:

// test.js
'use strict';

const server = require('./server');

// Do something on error event.
server.on('error', console.error);

// Do something on data event.
server.on('data', req => {
  console.log(req.headers);
});
 类似资料:
  • 问题内容: 如何使用与以下代码等效的node.js发出Http请求: 问题答案: 使用http客户端。 遵循以下原则:

  • 问题内容: 有人可以解释如何使用request.js池哈希吗? 在github上的注释说,这大约池: 池-包含这些请求的代理的哈希对象。如果省略,该请求将使用设置为节点的默认maxSockets的全局池。 pool.maxSockets-包含池中最大套接字数量的整数。 我有用于编写CouchDB实例的代码(请注意问号)。基本上,任何连接到我的Node服务器的用户都将彼此独立地写入数据库: 什么是高

  • 问题内容: 我正在用PHP构建一个REST Web服务客户端,此刻我正在使用curl来向该服务发出请求。 如何使用curl发出经过身份验证的请求(http基本)?我必须自己添加标题吗? 问题答案: 你要这个: Zend有一个REST客户端和zend_http_client,我敢肯定PEAR有某种包装。但是它很容易自己完成。 因此,整个请求可能如下所示:

  • 问题内容: 在实现代理服务器时,我将HTTP请求作为字符串发送,如下所示: GET http:// localhost:54321 / x HTTP / 1.1 主机:localhost:54321 缓存控制:无缓存 是否有内置的类来解析此请求? 问题答案: 我对这种解析的内置支持一无所知。如果您确实需要这样的解析器,则可以签出以下库: http //hc.apache.org/index.htm

  • 问题内容: 我想获取所有属于以下子项的标签: 我知道如何找到像这样的特定类的元素: 但是我不知道如何找到所有的孩子,而不是其他孩子。 就像我想选择: 问题答案: 尝试这个

  • 问题内容: 让我们建立一个简单的例子: 我如何全局转换发送请求的URL?本质上,我想为每个http请求添加一个URL。 我尝试过的是在应用程序启动时在包含URL的位置设置变量。但这不是我想要我的代码看起来像的样子: 我是否应该考虑研究是否正确?谁能给我一些基本的示例代码? 问题答案: 我有另一种使用带有$ http的请求拦截器的方法,它将在一个公共位置处理所有url。