Legendarniy
@Legendarniy

Скачивание PDF файла из response. Почему файл PDF пустой?

Суть проблемы в том, что не могу понять почему скачивается пустой (белые страницы) файл PDF?

По клику на сгенерированном списке товаров, у меня есть кнопка скачивания файла. При нажатии на нее, выстреливает экшн с id моего заказа (чтобы этот id вставить в url и получить ответ от сервера в виде PDF конкретной позиции). Реализовано это при помощи async await и выглядит так:
import { returns } from '../../services/api';
import { DOWNLOAD_PDF, DOWNLOAD_PDF_SUCCESS, DOWNLOAD_PDF_FAIL } from '../../constants';
import { createAction } from '../../utilities';
import fileDownload from '../../utilities/file-download';
import errorLogger from './error';

export const request = createAction(DOWNLOAD_PDF);
export const success = createAction(DOWNLOAD_PDF_SUCCESS, ({ response, id }) => {
    fileDownload(response, `return-${id}.pdf`);
    return { payload: { data: response, id } };
});
export const failure = createAction(DOWNLOAD_PDF_FAIL);

export default ({ id }) => {
    return async dispatch => {
        try {
            dispatch(request());
            const response = await returns.getPdf({ id });
            dispatch(success({ response: response.data, id }));
        } catch (error) {
            dispatch(
                failure({
                    payload: {
                        message: 'Неудалось скачать PDF',
                        stack: error.stack,
                    },
                }),
            );
            errorLogger(error, DOWNLOAD_PDF);
        }
    };
};


fileDownload это мой хелпер, который выглядит так:
export default function (data, fileName) {
    const byteNumbers = new Array(data.length);
    for (let i = 0; i < data.length; i += 1) {
        byteNumbers[i] = data.charCodeAt(i);
    }
    const byteArray = new Uint8Array(byteNumbers);
    const blob = new Blob([byteArray], { type: 'application/pdf' });

    console.log(blob);

    const link = document.createElement('a');
    const url = window.URL.createObjectURL(blob);

    link.style = 'display: none';
    link.href = url;
    link.download = `${fileName}`;

    document.body.appendChild(link);

    link.click();

    window.URL.revokeObjectURL(url);
    document.body.removeChild(link);
}


Тут я пытаюсь собрать посимвольно (?) файл ориентируясь на MDN

Но в итоге у меня файл пустой (видимо что-то с кодировкой или около того).

Пока пробовал решить вопрос, запустил этот код из консоли браузера (Хром)
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://<сайт>/{мой id}', true);
xhr.responseType = 'blob';
xhr.setRequestHeader("Authorization-Domain", "http://");
xhr.setRequestHeader("Authorization-Session", "");
xhr.onload = function(e) {
if (this.status == 200) {
    
const blob = new Blob([this.response], { type:'application/pdf' });

const link = document.createElement('a');
const url = window.URL.createObjectURL(blob);

link.style = 'display: none';
link.href = url;
link.download = `${name}`;

document.body.appendChild(link);

link.click();

window.URL.revokeObjectURL(url);
document.body.removeChild(link);
    
}
};
 
xhr.send();

И файл скачался как надо. Заголовки авторизационные у меня есть и собираются в момент когда веду обращение к беку.
Вес файла скаченный через консоль хрома 69кб, через хелпер 65кб.
В console.log(blob) в моем хелпере выводится следующее: Blob(64061) {size: 64061, type: "application/pdf"}.

Что я делаю не так? И почему у меня скачивается пустой (без букв и пр) файл PDF?
  • Вопрос задан
  • 1988 просмотров
Решения вопроса 1
Legendarniy
@Legendarniy Автор вопроса
В общем, нашлось решение. Ходил вокруг него много раз, но благодаря Александру Таратину, который еще раз о нем сказал и удалось решить проблему.

Проблема крылась в том, что у меня есть отдельный файл, который создает в запросе свои header и httpConfig'и и надо было лишь добавить туда responseType: 'blob'

Вот так

export const getPdfConfig = axios.create({
    ...httpConfig,
    responseType: 'blob',
    headers: {
        ...customHeaders,
        'Content-Type': 'application/pdf',
    },
}).get;


Ну а затем использовать fileSaver.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Taraflex
@Taraflex
Ищу работу. Контакты в профиле.
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы