2012-09-05 58 views
1

我正在通過定位標記向用戶提供.pdf文檔。但是,通過錨標籤提供完整文檔路徑會暴露服務器目錄結構。下面是一個示例文檔的位置: mydomain.com/_webstuff/docs/proj03/sub01/111.pdf使用.htaccess在提供文件時隱藏目錄結構

我試圖創建接受了「proj03/SUB01/111.pdf」部分一個.htaccess,和重定向到上面的完整URI。

的HTML的話,應該是這樣的:

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

這是unworking 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網址前加斜槓,具體如下:

新FETCH.PHP

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

無論其...我的設計仍然是錯誤的,因爲文檔顯示地址欄中的真實文檔路徑。也就是說,當瀏覽器窗口中顯示.pdf文檔時,所有人都可以看到完全限定的URI。我太聰明瞭一半。回到我之前的評論:「我確定有更好的方法來做到這一點。」

建議?

回答

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。

+0

這是使用.htaccess的首選方法,它允許您使用任何所需的URL結構,然後在服務器上無縫重寫。 –

+0

這真是太棒了。謝謝。 – gibberish

1

我不知道爲什麼你需要隱藏你的目錄結構,但沒有php的簡單解決方案就是在你的下載部分的根目錄上建立一個符號鏈接。

在linux下 - 而在網絡的根目錄 - 這將是這樣的:

$ ln -s _webstuff/docs downloads 

,然後在下面_webstuff/docs所有的網站結構將可低於downloads爲好。

這樣,您甚至可以將web敏感目錄之外的敏感目錄設置爲最安全的解決方案,並且只需通過http創建符合鏈接的目錄即可。

+0

謝謝Jeroen,這是一個好主意。一個擺脫並反思。 – gibberish

2

如果你不想顯示你的URL結構,那麼你應該避免完全重定向。

我個人會做的是使用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文件夾的根目錄。

使用此方法,您根本不需要顯示文件的路徑,並且單擊頁面上的錨鏈接將不會執行任何重定向,它只會強制下載文件,用戶甚至不會知道他們正在重新路由。

+0

我也這麼想過,但是當文件變得非常大時,這不會起到很好的作用,還是會呢? – jeroen

+0

我無法確定 - 我已經在PDF文件上使用了40-50MB這樣的腳本,沒有問題,但我相信它完全取決於服務器的內存限制。下面是一個很好的例子,它通過將文件「分塊」成較小的大小以便服務器不超時來克服這個問題:http://www.php.net/manual/ru/function.readfile.php#99406 – Drew

+0

Ouch,在俄羅斯;-) – jeroen