这是我的超文本传输协议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. 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
来完成繁重的工作,这样你就不必了。你会注意到代码急剧减少。以下是它的步骤:
干得好:
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)