好吧,我试图在成功验证get请求后使用node.js提供apk文件。为此,我正在使用以下形式的api调用:
GET /apk/?username=user&token=a_token_goes_here
请注意,实际身份验证是通过在请求标头上发送凭据来执行的(例如,在那里显示用户名和密码)。身份验证成功,当我还验证用户的个性化令牌是否正确时,我现在是时候将文件实际提供给客户端了。为简单起见,处理程序代码的关键部分如下所示:
Peer.find({"username": request.credentials.peer.username}).exec(function (dbError, results) {
if (dbError) {
// handle error
}
if (results[0]._id.toString() === request.query.token) {
var absolutePath = THE_ACTUAL_PATH_TO_THE_APK_NOT_UNDER_PUBLIC;
var stat = fs.statSync(absolutePath);
response.writeHead(200, {
'Content-Type': 'application/vnd.android.package-archive',
'Content-Length': stat.size
});
var readStream = fs.createReadStream(absolutePath);
readStream.pipe(response);
return callback (null);
} else {
// error handling ...
}
}
我可以在服务器控制台上看到返回错误代码200。但是,在客户端,感觉好像ajax调用永远不会结束。这是因为我在通话之前禁用了ajax通话的按钮,我将在通话结束后立即再次激活该按钮。此外,我在浏览器控制台上有未打印的打印语句。实际上有些陈述是印刷的,但也许是整整两分钟,然后又一次,而不是一切。出于测试目的,我有一个文本文件,内容为
Here is your APK!
我担任apk。有人能指出我做错了什么吗?我很可能应该使用不同的函数来提供文件?我们如何强制客户端保存我们最终想要提供的文件来自上面的网址?
这里有一个次要问题(很可能是天真的):如果尝试下载文件的客户端使用非常糟糕的连接,会发生什么?这是否意味着node.js上的解决方案代码阻止所有其他传入调用,直到具有低带宽连接的人完成他/她的apk下载? (我希望不会,它以某种方式返回为块或其他东西)
添加ajax调用
$.ajax({
type: "GET",
url: theURL,
accepts: "application/vnd.android.package-archive",
beforeSend : function(xhr) {
xhr.withCredentials = true;
xhr.setRequestHeader("Authorization", "Basic " + mem.apk.username + ":" + mem.apk.password);
xhr.setRequestHeader("APP_KEY", mem.component.appKey);
xhr.setRequestHeader("APP_SECRET", mem.component.appSecret);
},
async: true,
contentType: "application/vnd.android.package-archive",
success: function(data, textStatus, jqXHR) {
var response = data;
console.log ("Data follows:");
console.log (data);
console.log ("Data ended");
},
error: function (data, textStatus, errorThrown) {
var response = JSON.parse(data.responseText);
console.log (JSON.stringify(response));
alert(response.message);
},
crossDomain: true,
username: mem.apk.username,
password: mem.apk.password
}).done(function() {}).fail(function() {}).always(function() {
$('#apkButton').prop("disabled",false);
});
答案 0 :(得分:1)
Express具有下载文件的功能
var apkFile = THE_ACTUAL_PATH_TO_THE_APK_NOT_UNDER_PUBLIC
if(!fs.existsSync(apkFile))
return res.status(404).send('Sorry no APKs here');
response.download(apkFile);
下载()的文档在http://expressjs.com/4x/api.html#res.download。如果您发送的文件名的扩展名为“.apk”,则Express会输出正确的标题。