提问者:小点点

InstagramAPI无法通过Nodejs工作


这是我的超文本传输协议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";

    header = {} (为空,假设header['Content-Type']==未定义为true)

    重要提示:sent_handler返回false

    “FINAL BODY”(变量post)的控制台. log返回“{}”

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

    有人知道吗?请询问是否需要更多信息


  • 共1个答案

    匿名用户

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

    1. Instagram的API只监听HTTPS,不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);
    

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

    3. Instagram OAuth流程有三个不同的步骤——看起来你试图(有点?)代理第一个重定向URL?但你也为这两个提供了相同的URL,而实际上是两个不同的endpoint。看起来你只是从如何在node.js中发出HTTPPOST请求中复制了代码?没有完全理解它在做什么或为什么。最重要的是,工作curl(Instagram示例代码)的Content-Type,使用multipart/form-data,而不是x-www-form-urlencoded

    解决方案

    因为你实际上还没有提供MCVE,所以我不能从损坏的代码中推断出你想做什么。我只能猜测,所以我将给你一个解决方案,使用request来完成繁重的工作,这样你就不必了。你会注意到代码急剧减少。以下是它的步骤:

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

    干得好:

    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)