Rails API / react / ax ios загружает поврежденный файл - PullRequest
1 голос
/ 13 июля 2020

Сначала я создал PDF-файл с помощью WickedPDF.

pdf_string = WickedPdf.new.pdf_from_string(
  ActionController::Base.new.render_to_string(template: 'v1/invoices/invoice_template', filename: 'test.pdf')
)

invoice.attachment.attach(
  io: StringIO.new(pdf_string),
  filename: 'test.pdf',
  content_type: 'application/pdf'
)

Мое приложение настроено для хранения файлов на s3 на prod и локально в dev. Для тестирования я также использовал s3 в dev, чтобы убедиться, что мой PDF-файл создается и сохраняется правильно. Поэтому после его создания я могу войти в систему aws и загрузить свой счет. Все отображается нормально.

Теперь у меня есть проблема с загрузкой счета. Когда я загружаю его, мой PDF-файл остается пустым.

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

    response.headers['Content-Type'] = @invoice.attachment.content_type
    response.headers['Content-Disposition'] = "inline; #{@invoice.attachment.filename}"

    response.headers['filename'] = @invoice.filename

    @invoice.attachment.download do |chunk|
      response.stream.write(chunk)
    end

Я также пробовал

    send_data @invoice.attachment.download, filename: @invoice.filename

и мой frontend (react) использует ax ios для его загрузки:

  const downloadInvoice = (id) => {
    axios.get(`/v1/invoices/${id}/download`)
      .then((response) => {
          const url = window.URL.createObjectURL(new Blob([response.data]));
          const link = document.createElement('a');
          link.href = url;
          link.setAttribute('download', response.headers.filename);
          document.body.appendChild(link);
          link.click();
      })
      .catch(() => {});
  };

Я немного смущен тем, почему мой загруженный PDF-файл пуст. Если я открою его в своих папках хранилища, он будет отображаться нормально. Кажется, есть проблема с тем, как я его загружаю.

Работает, если я создаю предварительно подписанный URL-адрес для S3 с:

s3 = Aws::S3::Resource.new(client: aws_client)
bucket = s3.bucket('bucket-name')
obj = bucket.object("@invoice.attachment.attachment.blob.key)

url = obj.presigned_url(:get)

Я могу отправить этот URL-адрес обратно в интерфейс и откройте его в новой вкладке, чтобы просмотреть PDF-файл. Но это не то, что я хочу ...

Спасибо за любую помощь!

1 Ответ

0 голосов
/ 13 июля 2020

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

Проблема с запросом ax ios.

Вместо:

  axios.get(`/v1/invoices/${id}/download`)

используйте

  axios.get(`/v1/invoices/${id}/download`, { responseType: 'arraybuffer' })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...