Как изменить имя файла подсказки в текстовом браузере Сохранить как диалог? - PullRequest
6 голосов
/ 20 августа 2010

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

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

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

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

Мысли?

-A

Ответы [ 5 ]

1 голос
/ 29 августа 2010

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

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

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

  • Мне нужно было установить мой заголовок content-disposition на attachment , чтобы предотвратить автоматическую потоковую передачу файлов при нажатии пользователем кнопки загрузки
  • мои файлы находятся на удаленном сервере
  • мои файлы большие (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-accel-redirect (эквивалент nginx x-sendfile) ) работает

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

Вместо того, чтобы делать спокойную загрузку, как это:

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, и у меня нет документации или тестов ^ скрывает ^

0 голосов
/ 01 декабря 2010

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

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

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

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

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

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


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

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

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

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

0 голосов
/ 20 августа 2010

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

0 голосов
/ 21 августа 2010

Почему это уродливое имя файла? Может быть, мы можем предложить лучший обходной путь, если знаем эту причину.

Если это имя не может быть изменено, то я предлагаю сделать переписку на лету перед отображением приглашения на загрузку.

0 голосов
/ 20 августа 2010

Вы можете сделать несколько умных переписываний URL на стороне сервера, например, переписать foo.mpeg в youveryuglyfilenamewithoutextension.

...