Rails API / react / axios 下载损坏的文件
Rails API / react / axios downloads corrupted file
首先我用 WickedPDF 创建了一个 pdf。
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 上和本地开发环境中。为了进行测试,我还在开发中使用了 s3 来验证我的 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
我的前端 (react) 使用 axios 下载它:
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 是空白的。如果我在我的存储文件夹中打开它,它显示得很好。我的下载方式似乎有问题。
如果我为 S3 创建一个预签名的 URL,那么有效的是:
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。但这不是我想要的...
感谢您的帮助!
以防有人对此感兴趣或遇到同样的问题。希望这能为您节省一些时间!
问题出在 axios 请求上。
而不是:
axios.get(`/v1/invoices/${id}/download`)
使用
axios.get(`/v1/invoices/${id}/download`, { responseType: 'arraybuffer' })
首先我用 WickedPDF 创建了一个 pdf。
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 上和本地开发环境中。为了进行测试,我还在开发中使用了 s3 来验证我的 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
我的前端 (react) 使用 axios 下载它:
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 是空白的。如果我在我的存储文件夹中打开它,它显示得很好。我的下载方式似乎有问题。
如果我为 S3 创建一个预签名的 URL,那么有效的是:
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。但这不是我想要的...
感谢您的帮助!
以防有人对此感兴趣或遇到同样的问题。希望这能为您节省一些时间!
问题出在 axios 请求上。
而不是:
axios.get(`/v1/invoices/${id}/download`)
使用
axios.get(`/v1/invoices/${id}/download`, { responseType: 'arraybuffer' })