我无法使send_file(Model.attachment.path)工作。 它不会失败,相反,它会向客户端发送一个0字节大小的文件,但文件名是正确的。
在我从Rails 2.3.8迁移到3之后,这个问题就开始发生了。
此次迁移中还发生了很多其他事情,我会尽力详细说明所有这些内容。
我通过ftp移动了附件,因为它们不是我的git存储库的一部分,因此它们通过cap deploy发布,而不是手动ftp远程(RHEL5)到本地(Win7),然后是本地(Win7)到远程(Ubuntu10)。 / p>
我知道FTPing不会通过传输保留文件权限,所以我所做的就是模仿我之前服务器上看到的chmod,因此它们几乎相同。 (用户/组不同,设置为root:root而不是olduser:olduser)。
从我的生产日志下载附件的请求的片段。
Started GET "/attachments/replies/1410?1277105698" for 218.102.140.205 at 2010-09-16 09:44:31 +0000
Processing by AttachmentsController#replies as HTML
Parameters: {"1277105698"=>nil, "id"=>"1410"}
Sent file /srv/app/releases/20100916094249/attachments/replies/UE0003-Requisition_For_Compensation_Leave.doc (0.2ms)
Completed 200 OK in 78ms
一切都没问题。我还要排除本地问题,我尝试在Win7和Ubuntu(在Vbox上)通过Chrome下载。
我还向你保证,这条道路确实是正确的。
root@li162-41:/srv/app/current# tail /srv/app/releases/20100916094249/attachments/replies/UE0003-Requisition_For_Compensation_Leave.doc
#
#
%17nw
HQ��+1ae����
%33333333333(��QR���HX�"%%��@9
��@�p4��#P@��Unknown������������G��z �Times New Roman5��Symbol3&�
�z �Arial5&�
总结一下这个问题,如何让send_file实际发送文件而不是假的0字节垃圾。
答案 0 :(得分:45)
send_file
有:x_sendfile
个参数,在Rails 3中默认为true
。
此功能通过返回带有路径的X-Sendfile标头的空响应,将流式下载卸载到前端服务器 - Apache(带有mod_xsendfile)或lighttpd。
Nginx使用X-Accel-Redirect
标题来实现相同的功能,但您必须这样做
在适当的环境文件中正确配置Rails:
config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'
Rails 3更新:此行已存在于production.rb
中,只需取消注释即可。
将sendfile on;
添加到您的nginx配置中以利用Rails发送的标头。
请记住,必须使用绝对路径,并且nginx必须具有对文件的读访问权。
别名文件的另一种方式:
为了更好的安全性,我在nginx中使用别名而不是绝对路径,
但是send_file
方法检查存在的别名失败的文件。
因此,我将行动改为:
head(
'X-Accel-Redirect'=> file_item.location,
'Content-Type' => file_item.content_type,
'Content-Disposition' => "attachment; filename=\"#{file_item.name}\"");
render :nothing => true;
答案 1 :(得分:18)
在Rails 3中,只需在production.rb
内部环境文件夹中取消注释 config.action_dispatch.x_sendfile_header ='X-Accel-Redirect'一行。
答案 2 :(得分:14)
是的,我在Rails 3中默认启用了X-sendfile也遇到了同样的问题。
如果你有大量的“send_file”电话, 您可以在config / environments / production.rb中注释掉以下行:
#config.action_dispatch.x_sendfile_header = "X-Sendfile"
然后send_file
方法开始完美运作。
因为我无法在Apache上安装x-sendfile扩展,所以我只是搜索了一下,发现了这个。
我希望它有所帮助。
答案 3 :(得分:3)
我过去曾遇到类似send_file()的问题,使用send_data()而不是保存我(例如send_data File.read(filename),:disposition =>'inline',:type => “一些/ MIME类型”)
答案 4 :(得分:0)
在轨道4上, 我意识到我的问题是我删除了我发送给用户的临时文件。
如果我没有删除文件,send_file可以正常工作。 我没有测试过薄,但它在乘客5作为独立服务器上运行良好