node.js:在获取请求成功validation后,提供文件(特别是apk)

好的,我试图在成功validationget请求时使用node.js来提供apk文件。 为此,我使用了一个表单的api调用:

GET /apk/?username=user&token=a_token_goes_here 

请注意,实际的身份validation是通过在请求的头部发送凭据来执行的(例如,在那里出现用户名和密码)。 身份validation成功,而且当我确认用户的个性化令牌是正确的时候,我真的可以把文件送回客户端。 为了简单起见,处理程序代码的关键部分如下所示:

 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调用没有结束。 这是因为我在呼叫之前closures了ajax呼叫的button,我将在呼叫结束后再次激活button。 而且,我在浏览器控制台上没有打印的打印语句。 其实一些陈述是印刷的,但也许2分钟后,然后再一次,而不是一切。 为了testing的目的,我有一个文本文件的内容

 Here is your APK! 

我作为apk。 有人能指出我在做什么错吗? 很可能我应该使用不同的function来提供文件? 我们如何强制客户端保存我们最终想要从上面的url提供的文件?

在这里,有一个次要问题(很可能是天真的):如果试图下载文件的客户端使用非常糟糕的连接,会发生什么? 这是否意味着node.js上的解决scheme代码阻止了所有其他来电,直到低带宽连接的人完成了他/她的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); }); 

Express有一个function来下载文件

 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); 

download()文档在这里http://expressjs.com/4x/api.html#res.download 。 如果您正在发送的文件名的扩展名是“.apk”,Express会提供正确的标题。