除非直接访问路由,否则Rails send_data将PDF作为字节流式传输

时间:2016-07-16 15:31:29

标签: ruby-on-rails ruby pdf amazon-s3

我有一个简单的Rails应用程序,可以从(私有)S3存储桶下载PDF并将其提供给浏览器。

# app/controllers/file_controller.rb
class FileController < ApplicationController
  def send_pdf
    s3_file = Aws::S3::Resource.new(
      region: "us-east-1",
      access_key_id: S3_ACCESS_KEY_ID,
      secret_access_key: S3_SECRET_ACCESS_KEY
    ).bucket('bucket-name').objects({prefix: "file_name"}).first.get.body.string

    send_data s3_file, filename: "FileName.pdf", type: 'application/pdf', disposition: 'inline'
  end
end


# config/routes.rb
Rails.application.routes.draw do
  get 'file', to: 'file#send_pdf', defaults: { format: 'pdf' }
end
  • 直接通过URL访问路线时,显示PDF正常。
  • 在新标签页中打开指向路线的链接时,会显示PDF正常。
  • 在同一选项卡中打开链接时,PDF数据将作为文本流式传输到浏览器。

在Rails 4和5中也会出现相同的行为。

我可能会遗漏一些令人讨厌的小问题,但是如何在相同的标签行为中打开以正确显示PDF而不是将字节作为文本?

更新1:

Chrome在Failed to load PDF document被修改为使用send_pdf而不是send_file时出现send_data错误。 (无论链接点击或直接路由请求如何,都会发生此错误。)

def send_pdf

  # S3 download

  temp_file = "#{Rails.root}/tmp/file.pdf"

  File.open(temp_file,"wb") do |f|
    f.write(s3_file)
    f.close
  end

  send_file temp_file, filename: "FileName.pdf", type: 'application/pdf', disposition: 'inline'

  File.delete(temp_file)
end

1 个答案:

答案 0 :(得分:0)

您是否尝试过send_file代替send_datahttp://apidock.com/rails/v4.2.1/ActionController/DataStreaming/send_file