【问题标题】:How to allow Binary File download using GRAPE API如何允许使用 GRAPE API 下载二进制文件
【发布时间】:2013-05-14 12:44:47
【问题描述】:

我想允许使用 ruby​​ 的 Grape API 下载二进制文件(.p12 文件)。这就是我正在尝试的。

get '/download_file' do
  pkcs12 = generate_pkcsfile 
  content_type('application/octet-stream')
  body(pkcs12.der)
end

使用 ActionController 的等效代码是

begin
  pkcs12 = generate_pkcsfile
  send_data(pkcs12.der,
            :filename => 'filename.p12')
end

问题是使用 API 下载的文件似乎是一个文本文件,每个字符都嵌入了 '\ufffd' 前缀,而使用浏览器下载的文件似乎是二进制文件。如何使用 GRAPE API 框架来允许下载通过 ActionController 的 send_data 下载的相同文件

【问题讨论】:

  • 与使用 ActionController 的请求的输出相比,您是否看到返回的 Content-Type HTTP 标头有所不同?它们有不同的字符集吗?
  • 当您在问题中比较 API 与浏览器时,实际上是“API 客户端加 API 路由”还是“浏览器加 ActionController 路由”?您有四种可能的组合,但不清楚您遇到了哪些问题 - 根据您的描述,问题实际上是否出在您的测试 API 客户端中?
  • 对。澄清一下,为了测试葡萄 API,我使用 curl/wget 作为客户端和 /download_file 作为端点。为了测试 ActionController,我使用 firefox 浏览器和 /keys 作为端点。换句话说,端点是不同的,但我想在两个端点上获得相同的行为。我检查了两个标题。浏览器/键响应标头有 'text/html; charset=utf-8' 作为内容类型,而葡萄响应标头具有 'application/octet-stream' 作为内容类型。但是切换葡萄代码以返回'text/html; charset=utf-8' 没有更改响应正文。
  • 我无法使用 curl 复制故障(即,我的答案中的代码使用 curl 可以正常工作)。但是,我正在直接在机架上运行 Grape 安装,并且想知道是否某些 Rails 中间件会干扰您。您是否尝试过不使用 Rails 直接托管 Grape 服务来排除这种情况?

标签: ruby-on-rails ruby api actioncontroller grape-api


【解决方案1】:

有问题#412#418 已被报告到grape github 页面。 与返回二进制文件和覆盖内容类型有关。

像这样返回二进制格式:

get '/download_file' do
    content_type "application/octet-stream"
    header['Content-Disposition'] = "attachment; filename=yourfilename"
    env['api.format'] = :binary
    File.open(your_file_path).read
end

【讨论】:

  • 为了安全起见,您可能还想使用File.binread(your_file_path)
【解决方案2】:

我认为您的 Grape 代码还可以,我使用浏览器和用于测试 API 的 Mac HTTP 工具(称为 GraphicalHTTPClient)测试了它的变体。我成功地从磁盘加载了一个二进制文件,并使用与您的代码几乎相同的 MIME 类型 'application/octet-stream' 传输它:

  get :download do
    data = File.open('binary_data').read
    content_type 'application/octet-stream'
    body data
  end

我建议您的问题出在 API 客户端和/或字符编码上(如 Stuart M 所建议的那样)。尽管到目前为止我们的讨论中出现的另一种可能性是某些 Rack 中间件被错误地触发,并修改了 Grape 的输出。

【讨论】:

  • 感谢大家的回复。我尝试切换葡萄端点以返回与 send_data 相同的字符编码;但是我没有看到响应主体有任何变化。我正在考虑同时切换 ActionController 和 Grape 端点代码以返回 Base64 编码字符串,以保证两个用例的行为相同。
  • 我怀疑这里的数据需要force_encoding。如果您可以在一个简单的 Grape 应用程序中重现此内容,请将其添加到 Grape 邮件列表中。
猜你喜欢
  • 1970-01-01
  • 2016-02-10
  • 1970-01-01
  • 1970-01-01
  • 2011-12-30
  • 2013-08-30
  • 2018-08-08
相关资源
最近更新 更多