Запуск загрузки большого файла из полностью сформированного ответа

Эта проблема

У меня есть конечная точка Node.js, которая правильно запускает загрузку произвольно большого файла при доступе с использованием следующего:

response.setHeader('Content-disposition', 'attachment; filename=' + fileName);
response.set('Content-Type', 'text/csv');
response.status(200);
result.pipe(response);

где result поток преобразования, и response Экспресс-объект

Это прекрасно работает при прямом доступе к конечной точке в Chrome, Firefox, Internet Explorer и т. Д. Проблема возникает при попытке достичь конечной точки при включенной аутентификации на основе токенов.

С точки зрения пользователя, когда они нажимают на кнопку, файл загружается.

Как заставить кнопку нажать на эту конечную точку с правильным токеном аутентификации в заголовке запроса и вызвать загрузку файла?

Мозговой штурм некоторых возможных подходов

  1. Когда пользователь нажимает кнопку, он запускает действие, которое обрабатывается программным обеспечением redux-api-middleware, которое делает GET запрос к конечной точке (с токеном аутентификации, автоматически включенным в запрос). Это промежуточное ПО сохраняет ответ в переменной, которая выбирается компонентом React. В этом компоненте React, если используемый браузер (например, Chrome и Opera) поддерживает потоки, response.body будет существовать, так что вы можете сделать что-то вроде следующего.

    if (response.body) {
        const csvReader = response.body.getReader();
        const textDecoder = new TextDecoder();
        const processCsvRow = (csvRow) => {
            if (csvRow.done) {
                console.log('Finished downloading file.');
                return Promise.resolve();
            }
    
            // Write to new file for user to download
            console.log(textDecoder.decode(csvRow.value, {stream: true}));
    
            return csvReader.read().then(processCsvRow);
        };
    
        csvReader.read().then(processCsvRow);
    }
    

    При таком подходе мне нужно было бы изучить, как обрабатывать данные, если они принимаются браузером без поддержки потока.

  2. Когда пользователь нажимает кнопку, он запускает действие, которое сохраняет конечную точку в хранилище Redux с помощью редуктора, который запускает компонент React для создания тега привязки, который автоматически щелкается.

    const link = document.createElement('a');
    document.body.appendChild(link); // Firefox requires the link to be in the body
    link.href = endPoint;
    link.target = '_blank';
    link.click();
    document.body.removeChild(link); // Remove the link when done
    

    где endPoint является конечной точкой, которая отвечает с файлом.

    Этот подход работает, когда аутентификация отключена. Когда аутентификация повторно включена, токен аутентификации должен каким-то образом вводиться в заголовок запроса тега привязки.

  3. Подобно #2, посмотрите на симуляцию щелчка якоря, создав HTTP-запрос со встроенным токеном аутентификации.
  4. Объединяя элементы из #1 и #2, когда пользователь нажимает на кнопку, запускается действие, которое отправляет GET запрос к конечной точке, который возвращает вторую временную незащищенную конечную точку, которая возвращает фактический ответ файла. Передайте эту временную незащищенную конечную точку тегу привязки в #2.
  5. Как-то перенаправить ответ на новую вкладку / окно.
  6. Передайте маркер аутентификации в качестве параметра URL (это проблема безопасности), затем используйте #2.
  7. Создайте новую конечную точку, которая генерирует и возвращает новый временный токен одноразового скачивания. Используйте эту новую конечную точку, чтобы получить временный токен для передачи в качестве параметра URL в исходную конечную точку через #2.

1 ответ

Решение

Я решил пойти с Подходом № 7 на данный момент.

Другие вопросы по тегам