Моя проблема возникла из-за того, что я не мог просто использовать 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-файлы содержат привилегированную информацию, вы, вероятно, захотите добавить аутентификацию токена в конечную точку и зашифровать файл.