且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Rails 使用 send_file 发送 0 字节文件

更新时间:2023-11-24 11:59:34

send_file:x_sendfile 参数,在 Rails 3 中默认为 true.此功能通过返回带有路径的 X-Sendfile 标头的空响应,将流式下载卸载到前端服务器 - Apache(使用 mod_xsendfile)或 lighttpd.

send_file has :x_sendfile param which defaults to true in Rails 3. This feature offloads streaming download to front server - Apache (with mod_xsendfile) or lighttpd, by returning empty response with X-Sendfile header with path.

Nginx 使用 X-Accel-Redirect 标头来实现相同的功能,但您必须在适当的环境文件中正确配置 Rails:

Nginx uses X-Accel-Redirect header for same functionality but you have to configure Rails properly in proper environment file:

config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'

Rails 3 更新:此行已存在于 production.rb 中,只需取消注释即可.

Rails 3 update: this line already exists in production.rb, just uncomment it.

sendfile on; 添加到您的 nginx 配置以利用 Rails 发送的标头.记住必须使用绝对路径并且nginx必须有文件的读权限.

Add sendfile on; to your nginx config to utilize header sent by Rails. Remember the absolute path must be used and nginx must have read access to file.

别名文件的另一种方法:

为了更好的安全性,我在 nginx 中使用别名而不是绝对路径,但是 send_file 方法会检查是否存在以别名失败的文件.因此,我将我的操作更改为:

For better security I use aliases in nginx instead of absolute paths, however send_file method checks existence of file which fails with alias. Thus I changed my action to:

  head(
        'X-Accel-Redirect'=> file_item.location,
        'Content-Type' => file_item.content_type,
        'Content-Disposition' => "attachment; filename="#{file_item.name}"");
  render :nothing => true;