3

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

所以,假设我有一个文件 /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 有标题,只是通过 /download/ 请求 /gallery/* 被重写。

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

#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 的解决方案。

4

3 回答 3

2

在偶然发现您的示例之后,我只是这样做了;-) 我很确定您只需在最新示例中将“目录/var/www/download”部分更改为“位置/下载”就可以了.

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

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

我在工作设置中拥有的是:

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

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

Avoiding PHP for this have the added benefit that you can serve these images and potentially huge video files (as in my case) with a lightweight static Apache server, not a memory-hog PHP back-end process.

于 2010-07-08T16:11:06.070 回答
1

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

<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,后者依次处理请求并强制显示 saveas 对话框。

保罗

于 2010-03-02T17:21:51.730 回答
1

简单的php解决方案:

下载.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>
于 2010-03-02T17:24:10.900 回答