【问题标题】:External API Calls With Express, Node.JS and Require Module使用 Express、Node.JS 和 Require 模块进行外部 API 调用
【发布时间】:2017-01-11 02:11:06
【问题描述】:

我的路线如下:

var express = require('express');
var router = express.Router();
var request = require('request');

router.get('/', function(req, res, next) {
  request({
    uri: 'http://www.giantbomb.com/api/search',
    qs: {
      api_key: '123456',
      query: 'World of Warcraft: Legion'
    },
    function(error, response, body) {
      if (!error && response.statusCode === 200) {
        console.log(body)
      }
    }
  });
});

module.exports = router;

我正在尝试对 Giant Bomb API 进行 API 调用,以恢复它所拥有的关于魔兽世界的所有数据。

问题是,路由刚刚加载;它不做任何事情或不超时,它只是持续加载。

我不知道我做错了什么,但话虽如此......我也不知道什么是对的。我正在努力学习。

任何帮助都会很棒。

谢谢

【问题讨论】:

  • 第一个答案应该会给你一些关于发生了什么的线索......但是,你能详细说明“它只是连续加载”吗?这样,您的意思是请求永远不会完成吗?路线永远不会解决?您是否有任何迹象表明情况确实如此?或者你只是没有得到回应?
  • qs 在您的请求中代表什么?

标签: javascript node.js


【解决方案1】:

您需要从request() 获取数据并将其作为对原始网络服务器请求的响应发送回。它只是不断加载,因为您从未对原始请求发送任何类型的响应,因此浏览器只是坐在那里等待响应返回,最终它会超时。

由于request() 支持流,您可以像这样使用.pipe() 非常简单地将数据作为响应发回。

var express = require('express');
var router = express.Router();
var request = require('request');

router.get('/', function(req, res, next) {
  request({
    uri: 'http://www.giantbomb.com/api/search',
    qs: {
      api_key: '123456',
      query: 'World of Warcraft: Legion'
    }
  }).pipe(res);
});

module.exports = router;

这会将.pipe() request() 的结果转化为res 对象,它将成为对原始http 请求的响应。

相关答案在这里:How to proxy request back as response


2021 年编辑。request() 库现已弃用,不再推荐用于新代码。有很多alternatives 可供选择。我最喜欢的是got() 库。上面可以这样使用它来完成。这也升级为使用pipeline() 函数,它是.pipe() 的更好版本,具有更完整的错误处理。

const router = require('express').Router();
const got = require('got');
const { pipeline } = require('stream');

router.get('/', function(req, res) {
  const dataStream = got.stream({
      uri: 'http://www.giantbomb.com/api/search',
      qs: {
        api_key: '123456',
        query: 'World of Warcraft: Legion'
      }
  });
  pipeline(dataStream, res, (err) => {
      if (err) {
          console.log(err);
          res.sendStatus(500);
      }
  });
});

module.exports = router;

【讨论】:

  • 很好的答案。我正在尝试使用类似的设置,但我也想使用 Node apicache,并且已经说过 apicacheexpress 配合得很好,此设置将有助于中间件缓存外部 API 响应。
  • request 已于 2020 年 2 月 11 日弃用。
  • @JaydeepMor - 我使用got() 库添加了答案的一个版本。
【解决方案2】:

对于 Express 中的每条路由,都需要发送响应(部分或完整)或致电 next,或两者都做。您的路线处理程序两者都不做。试试

var express = require('express');
var router = express.Router();
var request = require('request');

router.get('/', function(req, res, next) {
  request({
    uri: 'http://www.giantbomb.com/api/search',
    qs: {
      api_key: '123456',
      query: 'World of Warcraft: Legion'
    },
    function(error, response, body) {
      if (!error && response.statusCode === 200) {
        console.log(body);
        res.json(body);
      } else {
        res.json(error);
      }
    }
  });
});

module.exports = router;

并查看此路由处理程序响应的数据。

【讨论】:

  • 感谢您的输入,但不幸的是我得到了相同的结果。如果我让页面加载足够长的时间,我会收到一条错误消息,指出页面无法正常工作,并且它没有发送任何内容。
  • 我尝试遵循此解决方案,但“请求”模块已被弃用。
【解决方案3】:

对于 Laravel 用户,

如果没有,首先安装npm i axios包。

var axios = require('axios');

var config = {
    /* Your settings here like Accept / Headers etc. */
}

axios.get('http://local.dev/api/v1/users', config)
.then(function(response) {
    console.log(response.data);
    console.log(response.status);
    console.log(response.statusText);
    console.log(response.headers);
    console.log(response.config);
});

希望它对某人有所帮助!

【讨论】:

    猜你喜欢
    • 2012-01-20
    • 1970-01-01
    • 2018-03-24
    • 2013-03-04
    • 2017-02-25
    • 2023-03-26
    • 1970-01-01
    • 2020-07-17
    • 2015-01-30
    相关资源
    最近更新 更多