Отправка файла клиенту из Node.js с помощью Express - PullRequest
0 голосов
/ 01 февраля 2019

У меня уникальная ситуация с точки зрения сложности.

Мне нужно отправить HTML на сервер, заставить сервер преобразовать HTML в PDF, отправить этот PDF обратно клиенту, а затем загрузитьPDF с использованием кода на стороне клиента.

Я должен сделать это так, потому что я использую маршрутизацию на стороне клиента, поэтому единственный способ получить доступ к моей конечной точке, которая должна выполнить это действиечерез GET-запрос с Ajax или Fetch из клиентского JavaScript.Мне известно о res.sendFile(), но он пытается отобразить файл в браузере - я этого не хочу - скорее, я хочу иметь возможность использовать клиентский код для загрузки файла.

Можно ли в таком случае отправить файл PDF из временного хранилища на сервере клиенту, позволяя клиентскому коду в дальнейшем делать с файлом все, что он хочет - в моем случае, загружая его?

Я не верю, что должен предоставлять какой-либо код, потому что это скорее теоретический вопрос.

1 Ответ

0 голосов
/ 01 февраля 2019

Моя проблема возникла из-за того, что я не мог просто использовать res.sendFile() или res.download() из Express, потому что маршрут не был доступен через адресную строку браузера, скорее мое приложение использует маршрутизацию на стороне клиента, и поэтому яЯ должен был сделать HTTP-запрос GET через Fetch или XMLHttpRequest.

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

Тогда я решил с помощью Fetch сделать запрос на получение от клиента:

fetch('/route' , {
    method: 'GET',
    body: 'My HTML String'
});

На сервере у меня есть мой кодкоторый преобразует HTML-строку в PDF с помощью модуля узла HTML-PDF, а затем я преобразую этот файл в строку Base64, задав тип MIME и добавив data:application/pdf;base64,.

app.get('/route', (req, res) => {
    // Use req.body to build and save PDF to temp storage (os.tempdir())
    // ...
    fs.readFile('./myPDF.pdf', (err, data) => {
        if (err) res.status(500).send(err);
        res.contentType('application/pdf')
           .send(`data:application/pdf;base64,${new Buffer.from(data).toString('base64')}`);
    });
});

Назад наклиент, у меня есть вышеупомянутый запрос на получение, то есть мне просто нужно выполнить обещание, чтобы получить ответ:

fetch('/route', {
    method: 'POST',
    body: 'My HTML String' // Would define object and stringify.
})
.then(res => res.text())
.then(base64String => {
    // Now I just need to download the base64String as a PDF.
});

Чтобы сделать загрузку, я динамически создаю тег привязки,установите его href атрибут в строку Base64 в ответе от сервера, присвойте ему заголовок и затем программно щелкните по нему:

const anchorTag = document.createElement('a');
anchorTag.href = base64String;
anchorTag.download = "My PDF File.pdf"; 
anchorTag.click();

Итак, все вместе и на клиенте:

fetch('/route', {
    method: 'POST',
    body: 'My HTML String' // Would define object and stringify.
})
.then(res => res.text())
.then(base64String => {
    const anchorTag = document.createElement('a');
    anchorTag.href = base64String;
    anchorTag.download = "My PDF File.pdf"; 
    anchorTag.click();
});

Решение об использовании тега привязки для запуска загрузки пришло из другого ответа StackOverflow.Также важно отметить, что кодирование Base64 не очень эффективно.Существуют лучшие решения, но для моих целей Base64 будет работать нормально.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...