在 Node 中使用 PhoneGap Build API 包? 400 报错
昨天我在Node中使用了PhoneGap Build API包。我将它上传到了: https://github.com/germallon/phonegapbuildapi,我认为这是一个很有趣的试验。 Build API是真的简单,所以我认为我的代码也将是非常简单的。
首先,我开始阅读它的API部分。它可以获取到应用程序,图标,下载的东西,等等。PhoneGap允许每次请求一个令牌或通过身份验证信息。于是,我通过简单地方式验证每个请求,并且让大部分的API逻辑都调用两个通用函数:
function getConfig(path) { return { auth: username + ":" + password, host:"build.phonegap.com", port:"443", path:"/api/v1/"+path } }
//I handle doing the config get, http, string contact, etc function doCall(path, success, fail) { var options = getConfig(path); var req = http.get(options, function(res) { var resultString = ""; res.on("data", function(c) { resultString+=c; });
res.on("end",function() {
var result = JSON.parse(resultString);
success(result);
});
}).on("error", function(e) {
if(fail) fail(e);
});
}
exports.getAllApps = function(success,fail) { doCall("apps", function(res) { if(res.error && res.error.length && fail) fail(res.error); else success(res.apps); },function(e) { if(fail) fail(e); });
pgbuild = require("./pgbuild");
pgbuild.setUsername("ray@camdenfamily.com"); pgbuild.setPassword("isitmillertimeyet?");
//Test getting all the apps pgbuild.getAllApps(function(apps) { console.log("I got lots of apps! How many? "+apps.length); //console.dir(apps); }, function(e) { console.log("Oh snap, an error"); console.dir(e); });
pgbuild.createApp({ title:"New App for Testing", create_method:"file", file:"./forupload/index.html" }, function(res) { console.log("Ok in making an app"); console.dir(res); }, function(e) { console.log("I got an error: "); console.dir(e); } );
var http = require("https");
var fs = require("fs");
var path = require("path");
var username = "";
var password = "";
exports.setUsername = function(u) { username = u; }
exports.setPassword = function(p) { password = p; }
exports.createApp = function(options, success, fail) {
var httpOptions = getConfig("apps");
httpOptions.method = "POST";
//Detect if options.create_method is file, and if so, suck in the bits
//Fails if no .file
//Also note it doesn't support .zip yet.
if(options.create_method === "file") {
if(!options.file) throw new Error("Must supply file value.");
console.log("Need to read in a file:"+options.file);
//Shell out for file uploads
PreparePost(httpOptions,JSON.stringify(options), options.file, success);
} else {
//TODO
}
}
exports.getAllApps = function(success,fail) {
doCall("apps", function(res) {
if(res.error && res.error.length && fail) fail(res.error);
else success(res.apps);
},function(e) {
if(fail) fail(e);
});
}
exports.getApp = function(id, success, fail) {
doCall("apps/"+id, function(res) {
if(res.error && res.error.length && fail) fail(res.error);
else success(res);
},function(e) {
if(fail) fail(e);
});
}
exports.getAppIcon = function(id, success, fail) {
doCall("apps/"+id +"/icon", function(res) {
if(res.error && res.error.length && fail) fail(res.error);
else success(res.location);
},function(e) {
if(fail) fail(e);
});
}
//todo: Possibly validate platform? Should be: android,blackberry,ios,symbian,webos,winphone
exports.getAppDownload = function(id, platform, success, fail) {
doCall("apps/"+id +"/"+platform, function(res) {
if(res.error && res.error.length && fail) fail(res.error);
else success(res.location);
},function(e) {
if(fail) fail(e);
});
}
exports.getKeys = function() {
var platform = "";
if(arguments.length == 1) {
success = arguments[0];
} else if(arguments.length === 2) {
success = arguments[0];
fail = arguments[1];
} else if(arguments.length == 3) {
platform = arguments[0];
success = arguments[1];
fail = arguments[2];
}
var path = "keys";
if(platform != "") path+="/"+platform;
doCall(path, function(res) {
if(res.error && res.error.length && fail) fail(res.error);
else success(res.keys);
},function(e) {
if(fail) fail(e);
});
}
exports.getKey = function(platform, id, success, fail) {
doCall("keys/"+platform +"/"+id, function(res) {
if(res.error && res.error.length && fail) fail(res.error);
else success(res);
},function(e) {
if(fail) fail(e);
});
}
function getConfig(path) {
return {
auth: username + ":" + password,
host:"build.phonegap.com",
port:"443",
path:"/api/v1/"+path
}
}
//I handle doing the config get, http, string contact, etc
function doCall(path, success, fail) {
var options = getConfig(path);
var req = http.get(options, function(res) {
var resultString = "";
res.on("data", function(c) {
resultString+=c;
});
res.on("end",function() {
var result = JSON.parse(resultString);
success(result);
});
}).on("error", function(e) {
if(fail) fail(e);
});
}
//CREDIT: http://onteria.wordpress.com/2011/05/30/multipartform-data-uploads-using-node-js-and-http-request/
//Note that I modified his code quite a bit
//For file uploads
function EncodeFieldPart(boundary,name,value) {
var return_part = "--" + boundary + "\r\n";
return_part += "Content-Disposition: form-data; name=\"" + name + "\"\r\n\r\n";
return_part += value + "\r\n";
return return_part;
}
function EncodeFilePart(boundary,type,name,filename) {
var return_part = "--" + boundary + "\r\n";
return_part += "Content-Disposition: form-data; name=\"" + name + "\"; filename=\"" + filename + "\"\r\n";
return_part += "Content-Type: " + type + "\r\n\r\n";
return return_part;
}
//I expect the config options, the JSON data string, and file path
function PreparePost(httpOptions,data,file,success) {
var boundary = Math.random();
var post_data = [];
post_data.push(new Buffer(EncodeFieldPart(boundary, 'data', data), 'ascii'));
post_data.push(new Buffer(EncodeFilePart(boundary, 'text/plain', 'file', path.basename(file)), 'ascii'));
var contents = fs.readFileSync(file, "ascii");
post_data.push(new Buffer(contents, "utf8"));
post_data.push(new Buffer("\r\n--" + boundary + "--"), 'ascii');
MakePost(httpOptions,post_data, boundary,success);
}
function MakePost(httpOptions,post_data, boundary,success) {
var length = 0;
for(var i = 0; i < post_data.length; i++) {
length += post_data[i].length;
}
httpOptions.headers = {
'Content-Type' : 'multipart/form-data; boundary=' + boundary,
'Content-Length' : length
};
var post_request = http.request(httpOptions, function(response){
response.setEncoding('utf8');
var res="";
response.on('data', function(chunk){
res+=chunk;
});
response.on('end',function() {
success(JSON.parse(res));
});
});
for (var i = 0; i < post_data.length; i++) {
post_request.write(post_data[i]);
}
post_request.end();
}
英文原文 , OSChina.NET翻译
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
有意思的文章,可以去看看原文