2010-08-20 77 views
6

在我的网页(由Rails渲染)中,我想让用户右键单击照片以显示浏览器的另存为对话框,以让用户将照片保存到他们的硬盘中。如何更改文件名提示文本浏览器另存为对话框?

但是,我的服务器上的照片有不寻常的文件名(长十六进制名称),没有文件扩展名。 “另存为”对话框中的文件名提示具有这个丑陋的文件名。如果用户点击保存,他们将以一个命名不佳的文件结束,并且没有文件扩展名。

该网页知道照片的真实文件名(即来到了相机,例如名称)。有没有办法让我以编程方式覆盖“另存为”对话框的文件名提示,并带有我选择的文件名?

我知道Content-Dispostion头,并且通过此头可以指定一个文件名。但是,我认为为了能够使用这个头文件,我需要将整个文件加载/呈现给浏览器。如果要下载的资产是一部电影,那么该文件的加载可能会使浏览器超时......如果它是一个100毫克的视频。

想法?

-A

回答

0

你可以做一些聪明的服务器端的URL重写,例如像改写foo.mpegyouveryuglyfilenamewithoutextension

0

将Content-Disposition设置为“attachment; filename =”...这很好。 “附件”明确表示它不会在浏览器中呈现,但文件重命名仍然有效(或可能特别针对该情况)。

+0

嗨。 (前言通过说要下载的文件位于Rails服务器以外的服务器上。)在我的Rails控制器中,我可以设置Content-Disposition标头,但是如何在控制器中指定文件的URL下载。目前,我正在使用 r = Net :: HTTP.get_response() @content = r.body render:layout => false ...在我看来,我呈现<%= @content =>和I确实得到保存作为提示...但只有在文件完全加载后。对于视频文件,这需要很长时间。 但也许我不需要实际加载文件? 想法? – lagouyn 2010-08-20 19:32:53

+0

好的抱歉,这是一个Rails特有的问题,我不能说这么多。为了吸引更多Rails专家,我重申了你的问题。通常,您只发送标题,然后开始发送要传输的文件的二进制数据。不知道你描述的是否会导致这种行为,似乎并不如此。 – Nicolas78 2010-08-21 08:55:45

0

为什么这个丑陋的文件名在第一位?也许我们可以建议一个更好的解决方法,如果我们知道原因。

如果该名称无法更改,那么我建议在显示下载提示前进行重写。

1

我想我理解这里的问题是因为我不久前遇到(并解决了)至少它的一部分。

我有一些大的mp3's和我链接到他们对我的website

的几个问题

  • 我需要设置我的内容处置附件,以防止文件每当用户点击下载按钮时自动流式传输
  • 我的文件位于远程服务器上
  • 我的文件比较大(100MB)
  • 大文件会占用轨道控制器,如果处理不当

现在,迈克尔Koziarsky建议在this article该服务大文件时保持轨道的最佳方式过程中自由,是创建在您的控制器下载行为,以及这样做(注意使用x_sendfile =>真):

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

:x_sendfile告诉阿帕奇乐通过不占用轨道控制器进程的文件。代码的其余部分设置文件名和内容处置标题。

很好,但是我在heroku,像现在的其他人。所以我不能使用x_sendfile。

我发现我不能修改nginx的配置文件,无论是作为它的锁定由Heroku的所以这是不可能得到X-加速 - 重定向(Nginx的当量X-的sendfile)工作

所以,我决定增加一个perl script(见下文),我们的资产主机上的cgi-bin这个脚本设置内容处置,以附件并给我们的文件名了。

而不是做这样的宁静下载:

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 

的结果是,我的轨控制器不再投入战斗,当有人下载​​文件

我发现Perl脚本here连砍它一点为我工作:

#!/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但你可能有各种各样的使用它你的机器上的问题,因为我做重使用存储在bashrc中的ENV变量,并且我没有文档或测试^隐藏^

0

根据您的意见,您有几个问题。

  1. 你想使用你的Rails应用程序设置文件名。
  2. 该文件位于远程主机上,您的Rails应用程序充当中间人。
  3. 该文件可能很大,所以您希望在收到文件时将文件发送到浏览器,而不是排队整个文件。

只有使用Rails进行流式处理很棘手,原因有几个。

您需要一个HTTP客户端,让您在接收数据时访问邮件正文,而不是阻塞,直到您拥有了所有内容。 Net :: HTTP不是那个客户端。我不确定哪个库更适合。

一旦你有一个更加事件驱动的方式来获得在片文件,你可以通过一个进程来渲染: render :text => proc { |response, output| ... }

output可以像一个IO对象使用。不过,有些服务器在发送之前可能会缓冲,所以这是需要注意的。


不会在Rails中处理字节混排。

如果您的网络服务器或Web服务器前的代理支持X-REPROXY-URL HTTP标头,则您的应用程序可以设置该标头,并且您的网络服务器或代理将流式传输该文件。

Perlbal是我所知道的支持该标题的唯一代理服务器。

Apache2模块是also available

相关问题