обратная разработка загрузка страницы профиля в формате HTML

#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, чтобы заставить его работать.

Я не пробовал это в браузере, поэтому могут быть некоторые незначительные синтаксические ошибки, но концептуально я думаю, что это близко.