无法使用HTTP模块Node.js Azure函数执行HTTP请求

时间:2019-06-04 21:33:35

标签: javascript node.js azure http azure-functions

我正在尝试使用javascript在azure函数上通过节点模块http发出http请求,并且由于某种原因http.request没有收到数据(没有错误打印,就像请求被阻止一样)。天蓝色的配置或代码有什么问题吗?我确实遗漏了一些明显的东西吗?

  

代码在本地js文件上运行正常

context.log('JavaScript timer trigger function ran!', timeStamp); 按预期打印,但context.log("SUCCESS", JSON.parse(data));完全没有打印。

也尝试了不同的库(请求,axios),但没有成功


    module.exports = async function (context, myTimer) {
        var timeStamp = new Date().toISOString();

        if (myTimer.IsPastDue)
        {
            context.log('JavaScript is running late!');
        }
        context.log('JavaScript timer trigger function ran!', timeStamp);  

        const http = require('http');
        http.get('http://myAPIurl', (resp) => {
        let data = '';

        // A chunk of data has been recieved.
        resp.on('data', (chunk) => {
          data += chunk;
        });

        // The whole response has been received. Print out the result.
        resp.on('end', () => {
          context.log("SUCCESS", JSON.parse(data));
        });

      }).on("error", (err) => {
      context.log("ERROR: " + err.message);
      });

    }

3 个答案:

答案 0 :(得分:1)

我使用Axios重写了您的代码。它具有对async / await的即开即用支持,并且简化了许多代码,使其可以按您期望的那样工作,因为它使异步代码的执行类似于同步代码。

我认为您可能遇到的主要问题是JavaScript中的所有内容都是异步的。结果,Azure Function运行时在异步函数完成之前退出,因为它不会像发出HTTP请求时的同步代码那样阻塞。如果要使用回调,则需要在回调函数内部调用context.done(),以便Azure函数不会在回调完成之前退出。通过使用异步/等待,您可以保证您的代码将在HTTP请求上阻塞,直到收到响应或超时为止。在下面的示例中,Axios将返回一个包含数据作为元素的响应对象。我正在使用解构操作提取数据,这使我可以登录data

const axios = require('axios');
const url = 'https://google.com';

module.exports = async function (context, myTimer) {

  try {
    const { data } = await axios.get(url);
    context.log(data);
    // do something with the data
  } catch (err) {
    context.error(err);
  }

  context.done();
}

要在Azure功能上安装程序包

  1. 转到Azure门户;选择您的Azure Function应用
  2. 选择Platform Features。然后在开发工具
  3. 下的Advanced Tools (Kudu)
  4. 使用文件浏览器,导航至site/wwwroot/。您应该在其中看到一个package.json文件,以及几个带有函数名称的文件夹。
  5. 从该目录运行npm install --save axios
  6. 要确认其有效,请使用铅笔图标编辑package.jsonaxios应该列在dependencies json元素下

答案 1 :(得分:1)

我一直基于您的代码回调。 我从定义中删除了async这个绰号,并在您的context.done处理程序中添加了对resp.end的调用(这表示函数结束时通知函数主机)

module.exports = function (context, myTimer) {
    var timeStamp = new Date().toISOString();

    if (myTimer.IsPastDue)
    {
        context.log('JavaScript is running late!');
    }
    context.log('JavaScript timer trigger function ran!', timeStamp);  

    const https = require('https');
    https.get('https://raw.githubusercontent.com/LearnWebCode/json example/master/animals-1.json', (resp) => {
    let data = '';

    // A chunk of data has been recieved.
    resp.on('data', (chunk) => {
      data += chunk;
    });

    // The whole response has been received. Print out the result.
    resp.on('end', () => {
      context.log("SUCCESS", JSON.parse(data));
      context.done(null, data);
    });

  }).on("error", (err) => {
    context.log("ERROR: " + err.message);
  });

}

另一种选择是将函数保留为async,但您需要使用基于promise的调用来代替回调。在某些情况下,可以通过使用util.promisify包装它们,然后使用await关键字

来实现。

答案 2 :(得分:0)

好吧,这听起来很奇怪,但是我在西欧服务器(由美国服务器安装)上创建了一个新功能,并且工作正常,请求网址指向欧盟服务器。

这是天蓝色的网络问题吗?我真的不知道