Установить Content-Type созданный файл с помощью Ruby File? - PullRequest
5 голосов
/ 09 января 2012

Я использую File.open для создания .csv файла на лету.

Но мне нужно установить Content-Type файла на binary/octet-stream, чтобы браузеравтоматически загрузит его, а не просто отобразит его содержимое в браузере.

Сам файл создается локально и затем загружается в Amazon S3.

Ответы [ 2 ]

19 голосов
/ 09 января 2012

Краткий ответ

Невозможно указать значение Content-Type в файловой системе при создании файла.На самом деле, это, вероятно, не лучший способ достичь своей цели.

Чтобы предложить браузеру загрузить файл, а не отображать его, вы можете оставить Content-Type: text/csv и добавить заголовок Content-Disposition: attachment или Content-Disposition: attachment; filename=<your custom filename>.csv, чтобы изменить имя файла в «Сохранить как ...»"Диалог.

Настройка Content-Disposition с использованием Paperclip и AWS :: S3

Чтобы установить заголовок Content-Disposition с использованием Paperclip, вы можете добавить ключ к определению has_attached_file: s3_headers.

has_attached_file :spreadsheet,
  :path => 'perhaps/a/custom/path/:class/:id/:filename',
  :or_maybe => 'other parameters',
  :s3_headers => { 'Content-Disposition' => 'attachment' }

Проблемы с типом содержимого

По умолчанию файл с расширением .csv должен классифицироваться как файл text/csv.Вы можете проверить это с помощью Mime::Type.lookup_by_extension('csv').to_s # => "text/csv".Если это не так, вы можете добавить text / csv в качестве пользовательского mime-типа, создав файл config/initializers/mime_types.rb и добавив:

Mime::Type.register 'text/csv', :csv

Однако это почти всегда не должно иметь место (если толькоWindows делает что-то необычное с типами контента; я тестировал только в Linux).

Примеры

Я привел два примера, которые вы можете проверить.Первым является CSV-файл, загруженный с типом text/plain mime, который заставляет браузер отображать его в браузере без загрузки (мой браузер загрузил text/csv файлов).

https://s3.amazonaws.com/stackoverflow-demo/demo.csv

Второй также имеет MIME-тип text/plain, но я добавил заголовок Content-Disposition: attachment; filename="mycustomname.csv"

https://s3.amazonaws.com/stackoverflow-demo/demo-download.csv

Вы заметите, что первая ссылка отображается в браузерев то время как вторая ссылка загружается с пользовательским именем mycustomname.csv.

Чтобы узнать почему, посмотрите на заголовки, используя curl -I.

$ curl -I https://s3.amazonaws.com/stackoverflow-demo/demo-download.csv
HTTP/1.1 200 OK
Content-Disposition: attachment; filename="mycustomname.csv"
Content-Type: text/plain

против

$ curl -I https://s3.amazonaws.com/stackoverflow-demo/demo.csv
HTTP/1.1 200 OK
Content-Type: text/plain

Примечание: несвязанные заголовки были удалены.

1 голос
/ 09 января 2012

Если вы используете Ruby on Rails, вы можете использовать send_data метод:

send_data csv_data, :type => 'text/csv; charset=iso-8859-1; header=present', :disposition => "attachment; filename=some_csv_file.csv"
...