Instagram API无法通过Nodejs工作

时间:2017-06-21 23:46:11

标签: node.js http

这是我的http POST代码,在localhost上运行:

if(headers['Content-Type'] == undefined)
        headers['Content-Type'] = 'application/x-www-form-urlencoded';

    var post_options = {
          host: host,
          path: path,
          port: port,
          method: 'POST',
          headers: headers
    };

    if(headers['Content-Type'] == "application/json"){
        post_options["json"] = true;
        var post_data = JSON.stringify(body);
    }else
        var post_data = querystring.stringify(body);

     var post_req = http.request(post_options, function(res) {

          var body = '';

          console.log("INSIDE CALLBACK HTTP POST");

          res.setEncoding('utf8');

          res.on('data', function (chunk) {
              body += chunk;
              console.log('Response: ' + chunk);
          });

          res.on('end', function () {
            var post = querystring.parse(body);
            console.log("FINAL BODY:",post);
          });

          //console.log("RESPONSE in http POST:",res);

      });

      // post the data
      console.log("WRITING HTTP POST DATA");
      var sent_handler = post_req.write(post_data);

      console.log("POST_REQ:",post_req);
      console.log("sent_handler:",sent_handler);

      post_req.end();

以下是我发送给Instagram的信息:

  • host =“api.instagram.com”
  • path =“/ oauth / access_token”
  • body如下:

    body [“client_id”] = CLIENT_ID;

    body [“client_secret”] = CLIENT_SECRET;

    body [“grant_type”] =“authorization_code”;

    body [“redirect_uri”] = AUTHORIZATION_REDIRECT_URI;

    body [“code”] = login_code;

    body [“scope”] =“public_content”;

  • headers = {}(空,假设标题['Content-Type'] == undefined 为真)

  • 重要提示: sent_handler返回false

  • “FINAL BODY”(变量post)的console.log返回“{}”

要注意:使用curl与api instagram工作的通信。所以我真的相信问题出在nodejs中这段代码的某些部分。

有没有人有任何想法?请询问是否需要更多信息

1 个答案:

答案 0 :(得分:0)

好的,有三个主要问题导致我失败,我可以看到。

1。 Instagram的API只能侦听HTTPS,而不是HTTP。标准http节点模块在这里工作不起作用;您至少需要使用https

2。您在条件语句中定义了一个名为post_data的变量:

if(headers['Content-Type'] == "application/json"){
    post_options["json"] = true;
    var post_data = JSON.stringify(body);
}else
    var post_data = querystring.stringify(body);

我们已经讨论过不要乱用隐含的大括号(不要这样做),但除此之外,你还要定义一个仅限于条件语句的局部变量并用数据填充它。一旦条件结束,它就会被销毁。您可以在console.log(post_data)之后立即检查 - 它是否为空。

3。 Instagram OAuth流程有三个不同的步骤 - 看起来您正试图(排序?)代理第一个重定向网址?但是当它实际上是两个不同的端点时,你也会为这两个网址提供相同的网址。看起来你只是复制了How to make an HTTP POST request in node.js?中的代码而没有完全理解它的作用或原因。最重要的是,Content-Type工作curl(Instagram示例代码)使用multipart/form-data,而不是x-www-form-urlencoded

<强>解决方案

由于您实际上还没有提供MCVE,因此我无法从破碎的代码中推断出您正在尝试做的事情。我只能猜测,所以我会给你一个使用request进行繁重工作的解决方案,这样你就不必这么做了。您会注意到代码的显着减少。以下是它的步骤:

  1. 生成隐式授权链接
  2. 创建一个侦听重定向并捕获身份验证代码的服务器
  3. 向Instagram发出POST请求以检索令牌
  4. 你走了:

    const querystring = require('querystring'),
          http = require('http'),
          request = require('request'),
          url = require('url')
    
    // A manual step - you need to go here in your browser
    console.log('Open the following URL in your browser to authenticate and authorize your app:')
    console.log('https://api.instagram.com/oauth/authorize/?' + querystring.stringify({
        client_id: "90b2ec5599c74517a8493dad7eff13de",
        redirect_uri: "http://localhost:8001",
        response_type: "code",
        scope: "public_content"
    }))
    
    // Create a server that listens for the OAuth redirect
    http.createServer(function(req, res) {
        // Regrieve the query params from the redirect URI so we can get 'code'
        var queryData = url.parse(req.url, true).query || {}
    
        // Build form data for multipart/form-data POST request back to Instagram's API
        var formData = {
            client_id: "90b2ec5599c74517a8493dad7eff13de",
            client_secret: "1b74d347702048c0847d763b0e266def",
            grant_type: "authorization_code",
            redirect_uri: "http://localhost:8001",
            code: queryData.code || ""
        }
    
        // Send the POST request using 'request' module because why would you do it the hard way?
        request.post({
            uri: "https://api.instagram.com/oauth/access_token",
            formData: formData,
            json: true
        }, function(err, resp, body) {
    
            // Write the response
            console.log(body)
            res.setHeader('Content-Type', "application/json")
            res.end(JSON.stringify(body))
        })
    
    }).listen(8001)