简体   繁体   English

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

[英]How to rewrite and set headers at the same time in Apache

I have a directory of images that alternately be viewed directly in the browser, and other times downloaded. 我有一个图像目录,可以在浏览器中直接查看,其他时候下载。

So, say I have a file /gallery/gal_4254.jpg. 所以,假设我有一个文件/gallery/gal_4254.jpg。

I want to make /download/gal_4254.jpg trigger a download of the image rather than view it. 我想让/download/gal_4254.jpg触发下载图像而不是查看它。 /download is empty, all the images are in /gallery. / download为空,所有图像都在/ gallery中。

I can map requests to the download dir to the other files successfully 我可以成功地将对下载目录的请求映射到其他文件

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

and I already can force downloads in the gallery dir by setting 我已经可以通过设置强制在gallery dir中下载

<Directory /var/www/gallery/>
    ForceType "image/jpg"
    Header set Content-Disposition "attachment"
</Directory>

so setting the headers is no problem. 所以设置标题是没问题的。 I don't actually want /gallery to have the headers though, just requests for /gallery/* through /download/ that are rewritten. 我实际上并不希望/ gallery有标题,只需要重写/ gallery / * through / download /。

But, I need to combine the two, so the request is mapped to the file in the other dir AND the file is given the attachment header. 但是,我需要将两者结合起来,因此请求被映射到另一个目录中的文件,并且文件被赋予附件头。

#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>

I've tried changing the order of the rewrite and header sections to no avail. 我试过改变重写和标题部分的顺序无济于事。 I think it loses the header when the request is rewritten to the other directory. 我认为当请求被重写到另一个目录时它会丢失标题。

Any suggestions on how to do this in Apache? 有关如何在Apache中执行此操作的任何建议?

I realize this could be done with PHP as well, which is why I posted it here vs. Server Fault. 我意识到这也可以用PHP完成,这就是我在这里发布它与服务器故障的原因。 A solution using PHP would be welcome also. 使用PHP的解决方案也是受欢迎的。

A combined solution could be the following setup. 组合解决方案可以是以下设置。 First change the directory entry: 首先更改目录条目:

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

The download.php should contain something like this (NOT TESTED): 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);
?>

This shouldd redirect all download requests to download.php which in turn handles the requests and forces the saveas dialog to appear. 这应该将所有下载请求重定向到download.php,而download.php又处理请求并强制显示saveas对话框。

Paul 保罗

Simple php solution: 简单的php解决方案

download.php 的download.php

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

.htaccess 的.htaccess

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

I just did this, after stumbling on your example ;-) I'm pretty sure you just have to change your "Directory /var/www/download" section to a "Location /download" in your latest example and you're OK. 我刚刚在你的例子上磕磕绊绊之后做了这件事;-)我很确定你只需要在最新的例子中将你的“目录/ var / www / download”部分改为“Location / download”,你就可以了。

Rationale is : "Directory" applies to the resulting physical directory, AFTER the rewrites have occured, whereas "Location" applies to the original URI, no matter any rewrites have occured to find the physical file. 基本原理是:“目录”适用于生成的物理目录,在重写发生之后,而“位置”适用于原始URI,无论是否发生任何重写以查找物理文件。

As mod_rewrite is a huge hack that applies at various times, the effect of your code is not very obvious. 由于mod_rewrite是一个在不同时间适用的巨大hack,因此代码的效果不是很明显。

What I have in my workjing setup is : 我在workjing设置中的内容是:

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

So URLs like /contents/myimage.jpg AND /contents/e-docs/myimage.jpg both get the Content-Disposition header, even though /contents/e-docs/myimage.jpg is actually the /e-docs/myimage.jpg file, as the rewrite says. 所以像/contents/myimage.jpg和/contents/e-docs/myimage.jpg这样的网址都获得了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. 为此避免使用PHP还有一个额外的好处,即您可以使用轻量级静态Apache服务器提供这些图像和潜在的大型视频文件(如我的情况),而不是内存占用的PHP后端进程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM