好吧,我正在尝试在成功验证 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 调用的按钮,并且我将在调用结束后立即再次激活该按钮。此外,我在浏览器控制台上有未打印的打印语句。实际上,有些语句被打印出来,但可能是 2 分钟后,然后又打印出来,而不是全部。为了测试的目的,我有一个文本文件与内容
Here is your APK!
我作为apk。有人能指出我做错了什么吗?我很可能应该使用不同的函数来提供文件?我们如何强制客户端保存我们最终想要通过上面的 URL 提供的文件?
这里,有一个次要问题(很可能是幼稚的):如果尝试下载文件的客户端使用非常糟糕的连接来下载文件,会发生什么?这是否意味着 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);
});