Использование JS для получения ответа send_data от Rails - PullRequest
0 голосов
/ 22 февраля 2019

У меня есть интерфейс VueJS, который подключен к интерфейсу Rails API.

В одной из конечных точек я использую WickedPDF для создания PDF.Когда я открываю сам URL в браузере, PDF скачивается нормально и работает точно так, как ожидалось.Когда я отправляю запрос через Vue, API отвечает странной строкой, которая выглядит следующим образом:

%PDF-1.4
1 0 obj
<<
/Title (��)
/Creator (��wkhtmltopdf 0.12.4)
/Producer (��Qt 4.8.7)
/CreationDate (D:20190222102025+02'00')
>>
endobj
3 0 obj
<<
/Type /ExtGState
/SA true
/SM 0.02
/ca 1.0
/CA 1.0
/AIS false
...

Я не совсем уверен, что это за тип данных?Сначала я думал, что это может быть BLOB, но понятия не имею.Я следовал логике, изложенной здесь , чтобы проанализировать ответ от моего rails api, который загрузил PDF в chrome.При открытии этого PDF-файла он пуст, а имя файла в верхней части браузера Chrome представляет собой комбинацию странных символов.Это заставляет меня думать, что я неправильно преобразовываю ответ, и в результате возникает некоторая проблема с кодировкой.

Вот мой код Rails API:

def pdf
  pdf_html = ActionController::Base.new.render_to_string(
    template: 'api/v1/exporters/pdf',
    layout: 'pdf',
    page_size: 'A4',
    formats: :html,
    encoding: 'utf8',
    margin: {
      top: 20,
      left: 20,
    }
  )
  pdf = WickedPdf.new.pdf_from_string(pdf_html)
  send_data(
    pdf,                                  
    filename: 'download.pdf',                     
    type: 'application/pdf',                      
    disposition: 'attachment'
  )
end

Вот функция JSпо ссылке выше.Я передаю тело ответа Rails (которое при регистрации консоли является странно выглядящим символом, установленным в первом блоке кода) в качестве единственного параметра:

showFile(blob){
  var newBlob = new Blob([blob], {type: "application/pdf"})

  if (window.navigator && window.navigator.msSaveOrOpenBlob) {
    window.navigator.msSaveOrOpenBlob(newBlob);
    return;
  } 

  const data = window.URL.createObjectURL(newBlob);
  var link = document.createElement('a');
  link.href = data;
  link.download="file.pdf";
  link.click();
  setTimeout(function(){
    window.URL.revokeObjectURL(data);
  , 100}
}

Может ли кто-нибудь помочь мне указать правильное направление относительно того, какправильно настроить это или как сделать это другим / лучшим способом?Даже подтверждение того, какой тип данных есть в ответе, может помочь мне.

1 Ответ

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

Если вы используете axios для вызова API, вы можете указать клиент для загрузки данных в виде BLOB-объектов.

import axios from 'axios';

axios
    .request({
       url: '/api-url-to-download-pdf',
       responseType: 'blob',
    })
    .then(response => response.data)
    .then(blob => {
        const data = URL.createObjectURL(blob );

        // ... do your stuff here ...
    .catch((err) => {
        // handle error
    });

Если вы используете fetch api для запроса API,

fetch('/api-url-to-download-pdf', {
    headers: {
        Accept: 'application/pdf',
    },
    responseType: 'arraybuffer'
})
    .then(response => {
        console.log(response);
        if (response.ok) {
            return response.blob();
        }
    })
    .then(blob => {
        const data = URL.createObjectURL(blob);

        // ... do your stuff here ...
    })
    .catch((err) => {
        // handle error
    });
...