Ruby on Rails中的send_data和send_file有什么区别?


Answers:


109
send_data(_data_, options = {})
send_file(_path_, options = {}) 

这里的主要区别是,您通过send_data传递DATA(二进制代码或其他),或通过send_file传递文件PATH 。

因此,您可以生成一些数据并将其作为嵌入式文本或附件发送,而无需通过send_data在服务器上生成文件。或者您可以使用send_file发送准备好的文件

data = "Hello World!"
send_data( data, :filename => "my_file.txt" )

要么

data = "Hello World!"
file = "my_file.txt"
File.open(file, "w"){ |f| f << data }
send_file( file )

为了提高性能,最好只生成一次文件,然后根据需要发送多次。所以send_file会更适合。

就流媒体而言,据我了解,这两种方法都使用相同的选项和设置,因此您可以使用X-Send或其他方法。

UPD

send_data并保存文件:

data = "Hello World!"
file = "my_file.txt"
File.open(file, "w"){ |f| f << data }
send_data( data )

谢谢@ fl00r。是否可以使用send_data函数将数据保存为文件然后发送?因为,我需要服务器中文件的副本。我该如何实现?
布莱克先生,

您的代码中有一个错误:应该是{ |f| f << data }
True Soft

嗨,我想知道这个答案是否仍然有用?我现在正在使用Rails 3.2.16,并且send_file必须使用文件本身而不是路径才能使其正常工作。只是想进行更新以防其他人遇到这种情况?
FireDragon 2014年

20

send_file可能比send_data更快

fl00r所述send_file采用路径和send_data数据。

因此send_file是的子集send_data,因为您需要文件系统上的一个文件:您当然可以只读取文件并send_data在其上使用。但是send_file可以更快,所以这是性能/通用性的折衷。

send_file可以更快,因为它知道路径,因此可以X-Sendfile在Apache(X-Accel-Redirect在Nginx上)发送标头而不是文件内容。

该头由反向代理(Apache或Nginx)使用,该反向代理通常在生产设置中的Rails前面运行。

如果X-Sendfile响应中存在,则反向代理将忽略当前的大多数响应,并构建一个新的响应,该响应将在给定路径下返回文件。

Client <---> Internet <---> Reverse proxy <---> Rails

由于反向代理高度专注于服务静态文件,因此它效率更高,并且比Rails(如果X-Sendfile要发送则不发送文件数据)执行速度更快。

典型的用例send_file是当您要控制静态文件的访问权限时:您不能将它们放在下面/public,否则它们将在Rails做出决定之前得到使用。在以下位置讨论此问题:保护Rails应用程序中公共/内容

为了使用X-Sendfile标题,您必须添加:

config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx

config/initializers/production.rb(或config/environment/production.rb在Rails 5.x中),而不是 application.rb,因为在开发中您没有代理服务器,并且您想send_file实际发送数据。

X-Sendfile在《资产管道指南》中进行了讨论。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.