使用.htaccess在提供文件时隐藏目录结构

时间:2012-09-05 21:59:44

标签: php .htaccess

我通过锚标记向用户提供.pdf文档。但是,通过anchor标记提供完整文档路径会公开服务器目录结构。这是一个示例文档位置: mydomain.com/_webstuff/docs/proj03/sub01/111.pdf

我正在尝试创建一个接受“proj03 / sub01 / 111.pdf”部分的.htaccess,并重定向到上面的完整URI。

然后,HTML将如下所示:

View <a href="proj03/sub01/111.pdf">111.pdf</a>

这是不工作的htaccess:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /fetch.php?f=$1

FETCH.PHP如下所示:

<?php
$f = $_GET['f'];
echo '<meta HTTP-EQUIV="REFRESH" content="0; url=_webstuff/docs/' . $f . '">';

我确信有更好的方法可以做到这一点。

编辑: MEA CULPA。我的错误是这样的:我必须在FETCH.PHP中的url之前添加一个斜杠,如下所示:

NEW FETCH.PHP

<?php
$f = $_GET['f'];
echo '<meta HTTP-EQUIV="REFRESH" content="0; url=/_webstuff/docs/' . $f . '">';

但是......我的设计仍然是错误的,因为文档显示了地址栏中的真实文档路径。也就是说,当.pdf文档显示在浏览器窗口中时,完全限定的URI可供所有人查看。我太聪明了一半。回到我之前的评论:“我确信有更好的方法可以做到这一点。”

建议?

3 个答案:

答案 0 :(得分:4)

如果你想只匹配某些模式,可以这样做。

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-z0-9]*)/([a-z0-9]*)/([a-z0-9]*).pdf$ /_webstuff/docs/$1/$2/$3.pdf [NC,L]

这将匹配/projNum/subNum/filename.pdf并重写URI。对于这种重写,查看器不会看到重写的URI。

答案 1 :(得分:2)

如果您不想显示网址结构,则应避免完全重定向。

我个人会做的是使用FETCH.PHP页面强制下载文件 - 只需使用PHP中的readfile()函数来获取信息。

这是我将在FETCH.PHP页面上放置的一个示例(显然这需要一些条件和检查以及什么不是,但它会给你一个想法)

$pdf_filename = "name-of-pdf-user-will-see.pdf";
ob_end_clean();
ob_start();
header('Pragma: public');
header('Expires: 0');
header ("Cache-Control: max-age=0, must-revalidate, post-check=0, pre-check=0");
header('Content-Description: File Transfer');
header('Content-Transfer-Encoding: binary');
header("Content-Type: application/octet-stream");
header('Content-Length: ' . filesize(realpath(dirname(__FILE__))."_webstuff/docs/".$f));
header("Content-Disposition: attachment; filename=\"$pdf_filename\"");
readfile(realpath(dirname(__FILE__))."_webstuff/docs/".$f);
ob_flush();
exit;

realpath(dirname(__FILE__))部分只允许您将服务器文件夹结构添加到该文件中 - 您应该在其周围添加dirname(),直到到达Web文件夹的根目录。

使用此方法您根本不需要显示文件的路径,并且单击页面上的锚点链接将不会执行任何重定向,它只会强制下载文件,用户甚至不会知道他们正在被重新安排。

答案 2 :(得分:1)

我不知道为什么你需要隐藏你的目录结构,但是没有php的简单解决方案是在你的下载部分的根目录上创建一个符号链接。

在linux中 - 在web-root目录中 - 可能是这样的:

$ ln -s _webstuff/docs downloads

然后_webstuff/docs下面的所有网站结构也会在downloads下方提供。

这样,您甚至可以将敏感目录放在web-root之外,这始终是最安全的解决方案,只需对需要通过http提供的目录进行符号链接。