¿Cuál es la diferencia entre send_data y send_file en Ruby on Rails?

Respuestas:

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

La principal diferencia aquí es que pasa DATA (código binario o lo que sea) con send_data o file PATH con send_file .

Por lo tanto, puede generar algunos datos y enviarlos como un texto en línea o como un archivo adjunto sin generar un archivo en su servidor a través de send_data . O puede enviar un archivo listo con send_file

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

O

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

Para mejorar el rendimiento, es mejor generar el archivo una vez y luego enviarlo tantas veces como desee. Así send_fileencajará mejor.

Para la transmisión, por lo que tengo entendido, ambos métodos usan el mismo conjunto de opciones y configuraciones, por lo que puede usar X-Send o lo que sea.

UPD

send_data y guardar archivo:

data = "Hello World!"
file = "my_file.txt"
File.open(file, "w"){ |f| f << data }
send_data( data )
fl00r
fuente
1
gracias @ fl00r. ¿Hay alguna forma de guardar los datos como archivo y luego enviarlos, usando la función send_data ?. Porque necesitaba una copia del archivo en mi servidor. ¿Cómo puedo lograr eso ?.
Mr. Black
Hay un error en tu código: debería serlo { |f| f << data }.
True Soft
Hola, me pregunto si esta respuesta sigue siendo relevante. Estoy usando Rails 3.2.16 ahora y send_filetuve que usar el archivo en sí, no la ruta para que funcione. ¿Solo quería actualizar en caso de que otros se encuentren con esto?
FireDragon
20

send_file puede ser más rápido que send_data

Como mencionó fl00r , send_filetoma una ruta y send_datalos datos.

Por send_filelo tanto, es un subconjunto de send_data, ya que necesita un archivo en el sistema de archivos: por supuesto, podría simplemente leer el archivo y usarlo send_data. Pero send_filepuede ser más rápido, por lo que se trata de una compensación de rendimiento / generalidad.

send_filepuede ser más rápido porque puede enviar el X-Sendfileencabezado en Apache ( X-Accel-Redirecten Nginx) en lugar del contenido del archivo, ya que conoce la ruta.

Este encabezado es consumido por el proxy inverso (Apache o Nginx) que normalmente se ejecuta frente a Rails en una configuración de producción.

Si X-Sendfileestá presente en la respuesta, el proxy inverso ignora la mayor parte de la respuesta actual y crea una nueva que devuelve el archivo en la ruta dada.

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

Esto es mucho más eficiente ya que el proxy inverso está altamente especializado en servir archivos estáticos y puede hacerlo mucho más rápido que Rails (que no envía los datos del archivo si X-Sendfilese enviarán).

El caso de uso típico de send_filees cuando desea controlar el permiso de acceso de archivos estáticos: no puede colocarlos debajo /publico de lo contrario se servirían antes de que Rails tenga la oportunidad de decidir. Esto se discute en: Protección del contenido del público / en una aplicación Rails

Para usar los X-Sendfileencabezados, debe agregar:

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

a config/initializers/production.rb(o config/environment/production.rben Rails 5.x), no application.rb , ya que en desarrollo no tiene un servidor proxy y desea send_fileenviar los datos.

X-Sendfilese analiza en la Guía de canalización de activos .

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
fuente