#javascript
#javascript
Вопрос:
Это процесс, состоящий из нескольких частей. На странице есть кнопка, которая позволяет мне загружать страницу в формате PDF, которую я пытаюсь встроить в расширение Chrome:
1.) нажата кнопка
2.) запускается api, проверяющий, готова ли страница к загрузке, это выглядит примерно так
{"error":false,"printError":false,"msg":"Not Ready","ready":false,"id":1108908001,"link":"streamPdf/1108908001"}
{"error":false,"printError":false,"msg":"Ready","ready":true,"id":1108908001,"link":"streamPdf/110890800"}
3.) Как только он считывается как готовый, выполняется следующий запрос
fetch("https://www.website.com/cap/people/streamPdf/1108908001"});
Это возвращает значение HTML страницы
4.) преобразуйте значение HTML в base64
5.) затем браузер извлекает PDF
fetch("data:application/pdf;base64," base64);
6.) Загрузка PDF
Однако, когда я копирую выборку для шага # 5 и вставляю ее в браузер, загрузка не запускается.
Я бы ожидал, что это вызовет файл. Есть ли что-то, чего мне не хватает для запуска создания PDF?
Код, который у меня есть до сих пор:
var canID = "someNUM"
fetch("https://www.website.com/cap/people/printStateAjax?id=" canID)
.then(resp=>resp.json())
.then(data=>{
if(data.msg == "Ready") {
console.log('ready')
fetch("https://www.website.com/cap/people/streamPdf/" canID)
.then(resp => {return resp.text()})
.then(data => {
var base64 = btoa(unescape(encodeURIComponent(data)))
console.log('1')
return base64
})
.then(base64 => {
fetch("data:application/pdf;base64," base64)
.then(resp => {return resp.blob()})
.then(blob => {
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
// the filename you want
a.download = 'test_pdf';
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url)
})
})
}
})
При этом загружается PDF-файл, но PDF-файл пуст. Что я делаю не так?
Комментарии:
1. там, где у вас есть,
.then(text => console.log(text))
я думаю, вам следует добавитьblob
найденную вами функцию. Этот фрагмент правильный. Вы помещаете ObjectURL какurl
и нажимаете на него с помощью javascript. такимblob
должен быть текст, который вы получили в конце вашего кода. Вы пробовали это?2. Я немного удивлен, что вам нужно 2 вызова выборки для получения данных PDF. Интересно, могли бы вы упаковать возврат из streamPdf / вызова непосредственно в
createObjectUrl
бит.3. да, обновляю свой код!
4. можете ли вы показать пример того, как это будет выглядеть?
5. вы правы, удаление выборки base64() устранило проблему!
Ответ №1:
Интересно, может ли сработать что-то более простое — например, это…
var canID = "someNUM"
fetch("https://www.website.com/cap/people/printStateAjax?id=" canID)
.then(resp=>resp.json())
.then(data=>{
if(data.msg == "Ready") {
console.log('ready')
fetch("https://www.website.com/cap/people/streamPdf/" canID,
{
headers: {
"Content-Type":"application/pdf"
}
}
)
.then(resp => resp.blob())
.then(blob => {
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
// the filename you want
a.download = 'test_pdf.pdf';
a.click();
window.URL.revokeObjectURL(url)
})
}
});
Это просто захватывает большой двоичный объект и передает его по ссылке.
Также я думаю, что вам на самом деле не нужно добавлять этот a
тег в DOM, чтобы заставить его работать.
Я не пробовал это в браузере, поэтому могут быть некоторые незначительные синтаксические ошибки, но концептуально я думаю, что это близко.