Создайте и загрузите PDF с ремиксом

Я получаю HTML-код от компонента и отправляю его в конечную точку, которая будет генерировать PDF-файл. После этого я хочу загрузить созданный PDF-файл.

Это код, который я использую для вызова конечной точки и отправки html в теле:

const formDataHtml = formData.get('html') as string;
const html = new URLSearchParams({ html: formDataHtml });
    
const response = await fetchApi(`/pdf/html2pdf`, {
    request,
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: html,
    shouldParseResponse: false,
    shouldStringifyBody: false,
});
    
if (!response.success) {
    return json({ error: response.error.message }, response.error.statusCode);
}
    
const pdfFileData = response.data as PdfFileData;
const pdfBuffer = await new Response(pdfFileData.body).arrayBuffer();
const pdfUint8Array = new Uint8Array(pdfBuffer);
    
return new Response(pdfUint8Array, {
    headers: {
        'Content-Type': 'application/pdf',
        'Content-Disposition': `attachment; filename=protokol.pdf`,
    },
}); 

А это кнопка «Загрузить PDF», которая запускает загрузку:

function DownloadPDFForm({endpoint, html, children}) {
    const fetcher = useFetcher<any>();
    const downloadRef = React.useRef<HTMLAnchorElement>(null);
    const args = { html };

    React.useEffect(() => {
        const response = fetcher.data;
        if (!response) return;

        const blob = new Blob([response], { type: 'application/pdf' });
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = 'file.pdf';
        a.click();
        URL.revokeObjectURL(url);
    }, [fetcher.data]);

    function onClick() {
        const formData = new FormData();
        formData.set('endpoint', endpoint);
        formData.set('intent', 'download-pdf');
        for (const [key, value] of Object.entries(args)) formData.append(key, value);

        fetcher.submit(formData, {
            action: '/api/manage-files',
            method: 'POST',
        });
    }

    return (
        <div className = {cn('flex items-center')}>
            <a className = "sr-only" ref = {downloadRef} href = {fetcher.data?.url}>
                DOWNLOAD
            </a>
            <button type = "button" onClick = {onClick}>DOWNLOAD PDF</button>
        </div>
    );
} 

При вызове конечной точки инициируется загрузка PDF-файла, но все страницы пусты. Чем больше formDataHtml, тем больше страниц я получаю в загруженном PDF-файле, хотя все страницы пусты.

ПРИМЕЧАНИЕ. formDataHtml, html не являются нулевыми, поскольку я записал их в console.info (также протестировано с использованием базового HTML).

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
238
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Мне пришлось немного покопаться, чтобы выяснить, в чем проблема, и, очевидно, это связано с сервером Remix. Мой обходной путь заключался в декодировании строки base64, возвращаемой с сервера:

const base64ToBuffer = (base64: string): ArrayBuffer => {
const binaryString = window.atob(base64); // Decode base64 string
const length = binaryString.length;
const bytes = new Uint8Array(new ArrayBuffer(length));

for (let i = 0; i < length; i++) {
    bytes[i] = binaryString.charCodeAt(i);
}

return bytes.buffer;
};

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