Node.js: служить файлу (в частности, apk) при успешной аутентификации по запросу get

Хорошо, я пытаюсь выполнить файл apk с помощью node.js при успешной аутентификации запроса на получение. Для этого я использую 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. Может кто-нибудь указать мне, что я делаю неправильно? Скорее всего, я должен использовать файл, используя другую функцию? Как заставить клиента сохранить файл, который мы в конечном итоге хотим использовать с 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);
});

Ответ 1

Экспресс имеет функцию для загрузки файлов

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. Express выдает правильные заголовки, если расширение имени файла, которое вы отправляете, является ".apk".