У чому різниця між send_data та send_file в Ruby on Rails?


Відповіді:


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

Основна відмінність тут полягає в тому, що ви передаєте DATA (двійковий код або інший) за допомогою send_data або файл PATH за допомогою send_file .

Таким чином, ви можете генерувати деякі дані та надсилати їх як вбудований текст або як вкладення, не створюючи файл на своєму сервері за допомогою 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 )

1
спасибі @ fl00r. Чи є спосіб зберегти дані як файл, а потім відправити, використовуючи функцію send_data ?. Тому що мені потрібна була копія файлу на моєму сервері. Як я можу цього досягти ?.
Містер Блек

У вашому коді є помилка: вона повинна бути { |f| f << data }.
Справжній м'який

Привіт, мені цікаво, чи ця відповідь все ще актуальна? Зараз я використовую Rails 3.2.16, і використовуючи send_fileмені довелося використовувати сам файл, а не шлях, щоб змусити його працювати. Просто хотів оновити на випадок, якщо інші стикаються з цим?
FireDragon

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

to config/initializers/production.rb(або config/environment/production.rbв Rails 5.x), ні application.rb , оскільки у розробці у вас немає проксі-сервера, і ви хочете send_fileфактично надіслати дані.

X-Sendfileобговорюється в Посібнику трубопроводу активів .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.