【问题标题】:Rails/Backbone .pdf rendering on client sideRails/Backbone .pdf 在客户端呈现
【发布时间】:2018-01-29 14:32:40
【问题描述】:

为了分离关注点,我们在服务器端制作了 Rails Api 等应用程序,在客户端制作了 Backbone/Marionette。今天,我们正尝试通过专用路由向我们的用户发送新生成的发票。它背后的想法如下:用户点击发票,向服务器发出请求,服务器发送文件,客户端显示/允许下载它。

在服务器端,invoice 方法如下所示:

def invoice
  @order = current_user.orders.with_uuid(params[:id])
  if @order
    @order.order_attachment.with_document_file do |file|
      File.open(file.path, 'r') do |f|
        send_data f.read, :filename => 'report.pdf',
                          :type => 'application/pdf',
                          :disposition => 'attachment'
      end
    end
  else
    render nothing: true, status: :not_found
  end
end

在客户端,我们用这个函数获取数据来测试我们的代码:

$.get("#{config.apiRootUrl}user/things/#{@model.attributes.id}/invoice", dataType: 'binary', processData: false)
  .complete (response) ->
    console.log response
  .fail (response) ->
    console.log response

响应看起来像(原始数据提取,因为它更长):

%PDF-1.4
%ÿÿÿÿ
1 0 obj
<< /Creator <feff0050007200610077006e>
/Producer <feff0050007200610077006e>
>>
endobj
2 0 obj
<< /Type /Catalog
/Pages 3 0 R
>>
endobj
3 0 obj
<< /Type /Pages
/Count 1
/Kids [5 0 R]
>>
endobj
4 0 obj
<< /Length 8033
>>
stream
q

q
128.000 0 0 57.000 36.000 699.000 cm
/I1 Do
Q
1 w
/DeviceRGB CS
1.000 1.000 1.000 SCN
36.000 649.000 m
191.856 649.000 l
S
[ ] 0 d

那么,问题来了。请记住,我们不能对 .pdf 下载使用不同的方法,例如给客户端一个 url 以直接下载 .pdf 文件并考虑以前的数据,有没有办法:

  • 在服务器端更好地指定内容,以便浏览器理解它是 pdf 文件而不是原始数据?
  • 使用客户端花式库从客户端收到的原始数据重建 pdf?
  • 解决此问题的任何其他解决方案。

感谢您的时间和帮助。

【问题讨论】:

  • 重定向到 invoice.pdf ?与disposition: 'inline'

标签: ruby-on-rails backbone.js marionette


【解决方案1】:

[未测试!] 在控制器中,我会将渲染部分包装在一个块中

    respond_to do |format|
      format.pdf {
      ...<your code>...

      }
    end

在客户端请求 invoice.pdf 时不指定数据类型

【讨论】:

    【解决方案2】:

    对于那些寻找如何处理来自 rest api 的包含 .pdf 的响应的人来说,答案在客户端。我们必须根据 api 响应创建该 blob 对象,以在客户端“重新构建”pdf。以下是我们用来实现此目的的示例:

       $.get("#{config.apiRootUrl}user/orders/#{@model.attributes.uuid}/invoice")
          .complete (response) ->
            blob = new Blob([response.responseText], type: 'application/pdf')
            url = URL.createObjectURL(blob)
            $a = $('<a />', {
              'href': url,
              'download': "#{Date.now()}.pdf",
              'text': "click"
            }).hide().appendTo("body")[0].click()
    

    【讨论】:

      猜你喜欢
      • 2020-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-11
      相关资源
      最近更新 更多