Как изменить диалоговое окно "Сохранить как" в текстовом приглашении к имени файла в браузере?

На моей веб-странице (отображаемой Rails) я хотел бы позволить пользователю щелкнуть правой кнопкой мыши по фотографии, чтобы открыть диалоговое окно браузера «Сохранить как», чтобы пользователь мог сохранить фотографию на свой жесткий диск.

Однако фотографии на моем сервере имеют необычные имена файлов (длинные шестнадцатеричные имена) без расширения файла. В приглашении к имени файла в диалоговом окне "Сохранить как" указано это уродливое имя файла. Если пользователь нажмет кнопку «Сохранить», он получит файл с плохим именем и без расширения.

Веб-странице известно настоящее имя файла фотографии (например, имя, полученное камерой). Есть ли способ программно переопределить приглашение имени файла в диалоговом окне «Сохранить как» с именем файла по моему выбору?

Мне известен заголовок Content-Dispostion и что через этот заголовок можно указать имя файла. Однако я думаю, что для того, чтобы иметь возможность использовать этот заголовок, мне нужно загрузить / отобразить весь файл в браузере. Если актив, который будет доступен для загрузки, представляет собой фильм, эта загрузка файла может привести к тайм-ауту браузера ... например, если это 100-мегабайтное видео.

Мысли?

-A


person lagouyn    schedule 20.08.2010    source источник


Ответы (4)


Я думаю, что понимаю проблему здесь, потому что я столкнулся (и решил) по крайней мере частично сам не так давно.

У меня есть несколько больших mp3, и я ссылаюсь на них в своих сайт

Несколько проблем

  • Мне нужно было установить в заголовке content-disposition значение вложение, чтобы файлы не передавались автоматически, когда пользователь нажимает кнопку загрузки.
  • мои файлы находятся на удаленном сервере
  • мои файлы большие (100 МБ)
  • большие файлы могут связывать рельсовые контроллеры, если с ними не обращаться должным образом

Теперь Майкл Козиарски советует в этой статье , что лучший способ сохранить ваши процессы rails свободными при обслуживании больших файлов - это создать действие загрузки в вашем контроллере и сделать что-то вроде этого (обратите внимание на использование x_sendfile => true ):

  def download
    send_file '/path/to/podcast.mp3', :type => 'application/octet-stream', :disposition => 'attachment', :filename=>'something.mp3', :x_sendfile=>true
  end

: x_sendfile сообщает apache пропустить файл, не привязывая процесс контроллера rails. Остальная часть кода устанавливает имя файла и заголовок размещения содержимого.

Отлично, но я нахожусь на героку, как все сейчас. Поэтому я не могу использовать x_sendfile.

Я обнаружил, что не могу изменить файл конфигурации nginx, так как он заблокирован heroku, поэтому было невозможно получить x-accl-redirect (эквивалент x-sendfile ) рабочий

Итак, я решил добавить сценарий perl (см. Ниже) в cgi-bin на нашем хосте-ассете, и этот скрипт устанавливает для content-disposition значение вложение и также дает имя нашему файлу.

Вместо такой спокойной загрузки:

link_to "download", download_podcast_path(@podcast.mp3)

мы просто связываемся с mp3, убедившись, что мы проходим через cgi-bin, чтобы скрипт perl вызывал каждый mp3, который покидает сервер

# I'm using haml
%a{:href=>"http://afmpodcast.com/cgi-bin/download.cgi?ID=#{@podcast.mp3}"}
  download

В результате мой контроллер rails больше не запускается, когда кто-то загружает файл.

Я нашел скрипт Perl здесь и немного порезал его, чтобы он работал для меня:

#!/usr/local/bin/perl -wT

use CGI ':standard';
use CGI::Carp qw(fatalsToBrowser);

my $files_location;
my $ID;
my @fileholder;

$files_location = "../";

$ID = param('ID');

open(DLFILE, "<$files_location/$ID") || Error('open', 'file');
@fileholder = <DLFILE>;
close (DLFILE) || Error ('close', 'file');

print "Content-Type:application/x-download\n";
print "Content-Disposition:attachment;filename=$ID\n\n";
print @fileholder

Мой код находится на github, но у вас, вероятно, возникнут всевозможные проблемы, используя его на своем компьютере в качестве Я активно использую переменные ENV, которые храню в bashrc, и у меня нет документации или тестов ^ скрывает ^

person stephenmurdoch    schedule 29.08.2010

Вы можете перезаписать URL-адрес на стороне сервера, например, переписать foo.mpeg на youveryuglyfilenamewithoutextension.

person Johan    schedule 20.08.2010

Установите Content-Disposition на "attachment; filename =" ... это нормально. «Вложение» явно означает, что оно не должно отображаться в браузере, переименование файла тем не менее работает (или, возможно, особенно в этом случае).

person Nicolas78    schedule 20.08.2010
comment
Привет. (Предисловите к этому, сказав, что файл для загрузки находится на сервере, отличном от сервера Rails.) В моем контроллере Rails я могу установить заголовок Content-Disposition, но тогда как мне указать в контроллере URL-адрес файла, который будет скачал. В настоящее время я использую r = Net :: HTTP.get_response () @content = r.body render: layout = ›false ... и, на мой взгляд, я визуализирую‹% = @content = ›и получаю сохранение как подсказка ... но только после полной загрузки файла. Для видеофайла это занимает слишком много времени. Но, может быть, мне действительно не нужно загружать файл? Мысли? - person lagouyn; 20.08.2010
comment
хорошо, извините, это проблема, связанная с Rails, о которой я не могу так много сказать. Я изменил теги вашего вопроса, чтобы привлечь больше экспертов по Rails. Обычно вы отправляете только заголовок, а затем начинаете отправлять двоичные данные для файла, который хотите передать. Понятия не имею, вызывает ли то, что вы описываете, такое поведение, не похоже. - person Nicolas78; 21.08.2010

Судя по вашим комментариям, у вас есть несколько проблем.

  1. Вы хотите установить имя файла с помощью приложения Rails.
  2. Файл находится на удаленном хосте, а ваше приложение Rails действует как посредник.
  3. Файл может быть большим, поэтому вы хотите, чтобы файл отправлялся в браузер по мере его получения, а не помещался в очередь.

Потоковая передача только с помощью Rails сложна по нескольким причинам.

Вам понадобится HTTP-клиент, который позволит вам получать доступ к телу сообщения по мере получения данных, а не блокировать, пока у вас не будет все. Net :: HTTP - не тот клиент. Я не уверен, какая библиотека лучше подходит.

Когда у вас будет более управляемый событиями способ разбить файл на части, вы можете передать процесс рендерингу: render :text => proc { |response, output| ... }

output можно использовать как объект ввода-вывода. Однако некоторые серверы могут буферизоваться перед отправкой, так что на это следует обратить внимание.


Было бы проще не обрабатывать перестановку байтов в Rails.

Если ваш веб-сервер или прокси перед вашим веб-сервером поддерживает HTTP-заголовок X-REPROXY-URL, ваше приложение может установить этот заголовок, и ваш веб-сервер или прокси будут передавать файл в потоковом режиме.

Perlbal - единственный известный мне прокси-сервер, который поддерживает этот заголовок из коробки.

Модуль Apache2 также доступен.

person cpm    schedule 01.12.2010