2009-09-12 30 views
3

我想保證我的PHP圖像上傳腳本和我不得不跳過的最後一道障礙,使用戶不能直接超出圖像,但服務器仍然可以在網頁上提供服務。我嘗試將文件夾的所有權和權限更改爲無效,因此我試圖將這些圖像存儲在public_html上方,並將其顯示在存儲在public_html中的頁面中。存儲和閱讀上面的圖像public_html

我的文件結構:

- userimages 
    image.jpg 
    image2.jpg 

- public_html 
    filetoserveimage.html 

我試圖鏈接到圖像中的userimages文件夾是這樣的:

<img src="../userimages/image.jpg"> 

但它不工作。有什麼我在這裏失蹤?如果您有任何更好的建議,請讓我知道。我試圖阻止公衆用戶執行他們可能上傳的潛在危險文件。就像一個額外的安全措施。謝謝!

回答

4

你想要的東西基本上是不可能的。

一個瀏覽器加載一個頁面(在一個非常基本的意義上)的方式是這樣的:

第1步:下載頁面。 第2步:解析頁面。 步驟3:下載頁面內容中引用的任何內容(圖像,樣式表,JavaScript等)

每個「下載」事件都是原子的。

你似乎只想爲那些剛剛下載了引用這些圖像的頁面的用戶提供圖像。

正如PHP Jedi所示,您可以通過PHP傳遞文件。您可以擴展他的代碼,並根據請求檢查HTTP_REFERER,以確保人們不會「抓住」圖像。

現在,通過PHP passthru腳本提供每張圖片效率不高,但它可以工作。

人們想要這樣做的最常見原因是爲了避免「盜鏈」 - 當人們在服務器上引用圖像的其他網站上創建圖像標籤時。當他們這樣做時,您會花費資源處理請求,並將其顯示在其他人的頁面上。

如果這就是你真正想避免的,你可以使用mod_rewrite來檢查引用者。

盜鏈/防盜鏈的一個體面的前瞻性的討論可以發現here

1

那麼,網頁瀏覽器將只能訪問public_html中的文件和文件夾。

1

如果public_html目錄是您的用戶的服務器的根目錄,則Apache無法提供任何不在該目錄之內/之下的內容。

如果你想要一個文件由Apache直接提供,你必須把它放在/下面public_html

+0

我如何使它所以只有Apache可以充當存儲在一個的public_html文件夾中的文件? – 2009-09-12 20:04:29

+1

Heu ...實際上,如果Apache能夠處理這些文件,那幾乎全部都是:它可以提供文件 - 任何人都可以訪問它們。 – 2009-09-12 21:51:22

3

使用圖像中繼腳本!

要爲public_html文件夾外部的圖像文件提供服務,您必須通過php腳本進行操作。例如,使圖像relay.php讀取是公共HTML外的圖片...

<?php 
header('Content-Type: image/jpeg'); 
$_file = 'myimage.jpg'; // or $_GET['img'] 
echo file_get_contents('/myimages/'.$_file); 
?> 

現在,$ _file可能是$ _GET參數,但它absolutley重要驗證輸入參數.. 。

現在你可以做一個<img src="image-relay.php?img=flower.jpg">訪問位於/myimage/flower.jpg一個爲Flower.jpg圖像...

+0

我不想通過提供大量圖像來重載PHP,並且不得不運行PHP腳本來執行此操作。你認爲這會導致許多訪問者的網站出現問題嗎?例如10k天 – 2009-09-12 20:30:38

+0

根據我自己的經驗,這會導致幾個問題,特別是如果其他網站或訪問者拉太多圖片,這可能會導致圖像過載/拒絕。 – 2017-09-08 02:57:20

1

我想你是誤會的事實,如果包含在圖像一個<img>標記,您的瀏覽器將發送完全相同的請求到網絡服務器以獲取它,如果您嘗試運行,它將被髮送到網絡服務器直接在瀏覽器中顯示圖片的src網址。

因此,無論是事情都起作用,或者兩者都不起作用。

周圍有黑客,涉及一個(PHP或其他)腳本,以確保請求圖像的IP在最後幾秒內也請求了HTML頁面(如果用戶在後面通過檢查引用者(它不能與HTTP協同工作,並且如果用戶禁用引用者),也不檢查。

如果你想確保只有一些用戶可以看到圖像(都通過<img>標籤和直接),你可以把圖像放在public_html之外,並有一個(PHP或其他)腳本,在服務之前驗證用戶的憑證圖片。

1

如果您使用的是Apache或lighttpd,則可以使用X-Sendfile標頭髮送不在Web根目錄中的文件(前提是您未更改mod_xsendfile的配置)。

要了解有關X-sendfile的更多信息,請參閱此site

此解決方案爲您提供最佳性能,因爲PHP不會發送該文件,但服務器會這樣做,因此PHP可以在服務文件時退出。

希望有所幫助。

+0

現在,這是一個漂亮的模塊。但我不知道readfile()(如果可能的話,它也使用內存映射文件)的優勢有多大。 – VolkerK 2009-09-13 11:48:08

+0

首先,對於較大的文件,您可以在最長執行時間後獲得PHP超時。另外,如果文件大於PHP可以分配的內存,則readfile()也不起作用,因爲readfile會將整個文件讀入內存。我知道這不是服務圖像時最關心的問題,但您仍然有記憶力優勢。 – 2009-09-13 11:58:14