Sự khác biệt giữa send_data và send_file trong Ruby on Rails là gì?


Câu trả lời:


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

Sự khác biệt chính ở đây là bạn chuyển DATA (mã nhị phân hoặc bất cứ thứ gì) với send_data hoặc tệp PATH với send_file .

Vì vậy, bạn có thể tạo một số dữ liệu và gửi nó dưới dạng văn bản nội tuyến hoặc dưới dạng tệp đính kèm mà không cần tạo tệp trên máy chủ của bạn qua send_data . Hoặc bạn có thể gửi tệp đã sẵn sàng với send_file

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

Hoặc là

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

Đối với hiệu suất, tốt hơn là tạo tệp một lần và sau đó gửi nó nhiều lần tùy thích. Như vậy send_filesẽ phù hợp hơn.

Đối với phát trực tuyến, theo như tôi hiểu, cả hai phương pháp này đều sử dụng cùng một loạt các tùy chọn và cài đặt, vì vậy bạn có thể sử dụng X-Send hoặc bất cứ điều gì.

UPD

send_data và lưu tệp:

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

1
cảm ơn @ fl00r. Có cách nào để lưu dữ liệu dưới dạng tệp và sau đó gửi, bằng cách sử dụng hàm send_data không ?. Bởi vì, tôi cần một bản sao của tệp trong máy chủ của mình. Làm thế nào tôi có thể đạt được điều đó ?.
Mr. Black

Có một lỗi trong mã của bạn: nó phải như vậy { |f| f << data }.
True Soft

Xin chào, tôi đang tự hỏi nếu câu trả lời này vẫn còn phù hợp? Tôi đang sử dụng Rails 3.2.16 và khi sử dụng, send_filetôi phải sử dụng chính tệp đó, không phải đường dẫn để nó hoạt động. Chỉ muốn cập nhật trong trường hợp những người khác gặp phải vấn đề này?
FireDragon

20

send_file có thể nhanh hơn send_data

Như fl00r đã đề cập , send_filecó một đường dẫn và send_datadữ liệu.

Do đó, send_filelà một tập hợp con của send_data, khi bạn cần một tệp trên hệ thống tệp: tất nhiên bạn có thể chỉ cần đọc tệp và sử dụng send_datatrên đó. Nhưng send_filecó thể nhanh hơn, vì vậy nó là một sự đánh đổi hiệu suất / tính tổng quát.

send_filecó thể nhanh hơn vì nó có thể gửi X-Sendfiletiêu đề trên Apache ( X-Accel-Redirecttrên Nginx) thay vì nội dung tệp, vì nó biết đường dẫn.

Tiêu đề này được sử dụng bởi proxy ngược (Apache hoặc Nginx) thường chạy trước Rails trong thiết lập sản xuất.

Nếu X-Sendfilecó trên phản hồi, proxy ngược sẽ bỏ qua hầu hết phản hồi hiện tại và tạo một phản hồi mới trả về tệp theo đường dẫn đã cho.

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

Điều này hiệu quả hơn nhiều vì proxy ngược rất chuyên biệt trong việc phục vụ các tệp tĩnh và có thể thực hiện nhanh hơn nhiều so với Rails (không gửi dữ liệu tệp nếu X-Sendfileđược gửi).

Trường hợp sử dụng điển hình send_filelà khi bạn muốn kiểm soát quyền truy cập của các tệp tĩnh: bạn không thể đặt chúng dưới quyền /publichoặc nếu không chúng sẽ được phục vụ trước khi Rails có cơ hội quyết định. Điều này được thảo luận tại: Bảo vệ nội dung công khai / trong ứng dụng Rails

Để sử dụng các X-Sendfiletiêu đề, bạn phải thêm:

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

đến config/initializers/production.rb(hoặc config/environment/production.rbtrong Rails 5.x), không application.rb , vì trong phát triển bạn không có một máy chủ proxy và bạn muốn send_fileđể thực sự gửi dữ liệu.

X-Sendfileđược thảo luận trên Hướng dẫn về đường ống nội dung .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.