如何在Apache中同时重写和设置标题

时间:2010-03-02 16:38:55

标签: php apache mod-rewrite attachment content-disposition

我有一个图像目录,可以直接在浏览器中查看,有时也会下载。

所以,说我有一个文件/gallery/gal_4254.jpg。

我想让/download/gal_4254.jpg触发图像的下载而不是查看它。 / download为空,所有图像都在/ gallery。

我可以将对下载目录的请求成功映射到其他文件

<Directory /var/www/download>
    RewriteEngine on
    RewriteRule (.*)$ /gallery/$1
</Directory>

我已经可以通过设置

强制在图库目录中下载
<Directory /var/www/gallery/>
    ForceType "image/jpg"
    Header set Content-Disposition "attachment"
</Directory>

所以设置标题没问题。我实际上并不希望/ gallery有标题,只需要/ gallery / * through / download /重写。

但是,我需要将两者结合起来,所以请求被映射到另一个目录中的文件,文件被赋予附件标题。

#does not work - just views the image like when it is viewed directly
<Directory /var/www/download>
    ForceType "image/jpg"
    Header set Content-Disposition "attachment"
    RewriteEngine on
    RewriteRule (.*)$ /gallery/$1
</Directory>

我已经尝试更改重写和标题部分的顺序无济于事。我认为当请求被重写到另一个目录时它会丢失标题。

有关如何在Apache中执行此操作的任何建议吗?

我意识到这也可以用PHP完成,这就是我在这里发布它与服务器故障的原因。使用PHP的解决方案也是受欢迎的。

3 个答案:

答案 0 :(得分:2)

组合解决方案可以是以下设置。 首先更改目录条目:

<Directory /var/www/download>
    RewriteEngine on
    RewriteRule (.*)$ download.php?getfile=$1
</Directory>

download.php应包含类似这样的内容(未测试):

<?php

if ($_GET['getfile']){
  $file = '/var/www/gallery/' . $_GET['getfile'];
}

$save_as_name = basename($file);   
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: no-cache');
header("Content-Type: application/octet-stream");
header("Content-Disposition: disposition-type=attachment; filename=\"$save_as_name\"");

readfile($file);
?>

这应该将所有下载请求重定向到download.php,而download.php又会处理请求并强制显示saveas对话框。

答案 1 :(得分:2)

简单的php解决方案:

的download.php

header('Content-Type: image/jpeg');
header('Content-Disposition: attachment; filename='.$_GET['img']);
readfile('gallery/'.$_GET['img']);

的.htaccess

<Directory /var/www/download>
    RewriteEngine on
    RewriteRule (.*)$ /download.php?img=$1
</Directory>

答案 2 :(得分:1)

我刚刚踩到你的榜样后就这样做了;-) 我很确定你只需要在最新的例子中将“目录/ var / www / download”部分更改为“位置/下载”,你就可以了。

原理是:“目录”适用于生成的物理目录,在重写发生之后,而“位置”适用于原始URI,无论是否发生任何重写以查找物理文件。

由于mod_rewrite是一个在不同时间适用的巨大黑客,因此代码的效果不是很明显。

我在workjing设置中的内容是:

<Location /contents/>
    Header set Content-Disposition "attachment"
</Location>
...
RewriteRule ^.*(/e-docs/.*)$   $1

所以像/contents/myimage.jpg和/contents/e-docs/myimage.jpg这样的网址都会获得Content-Disposition标头,即使/contents/e-docs/myimage.jpg实际上是/ e-docs /myimage.jpg文件,正如重写所说。

为此避免PHP还有一个额外的好处,即您可以使用轻量级静态Apache服务器提供这些图像和潜在的大型视频文件(如我的情况),而不是内存占用的PHP后端进程。