Coldfusion 隱蔽式下載



一般下載時,通常會使用 <a href="URL" /> 這種方式使用者下載,而 URL 大多的做法是指明檔案所在的位置例如  <a href="http://MySite.com/download/picture/myPicture.png">。

這種方式有幾個問題:

1、如果使用者取得此聯結位址後,可以單獨由此取得檔案或盜連,故被直接拿到的風險會很高,因為這個 URL 就是一個開放的位址。

2、由於直接指定檔案位置,很多時候檔案就會被瀏覽器直接開啟,而非下載存檔,對於大部分使用者來說,這是一個貼心的模式,但是對於很多需要下載的商業用途場合就很麻煩,使用者還必須在聯結上按『右鍵』選擇『另存檔案』的方式,操作相當不便。

3、無法設定檢查使用者取得檔案的條件。

因此,透過隱蔽式下載就是一種很好的方法。

程式碼:

<cfsetting enablecfoutputonly="yes">
<!--- 避免下載檔案遇到中文檔名無法正常下載問題而使用的功能,也可以避免使用者知道實際檔案儲存位置 --->
<!---
Arguments : file = 指定檔案名稱
--->
<cftry>
<!--- 判斷使用者來源聯結是否來自本伺服器 或是直接下載,當直接下載時 REFERER 會是 空值--->
    <cfif findnocase(CGI.SERVER_NAME,CGI.HTTP_REFERER) LTE 0>
    <cfthrow type="RefererError" message="#CGI.HTTP_REFERER#:不允許存取">
    </cfif>
<!--- 判斷參數是否存在 --->
<cfif not isdefined("file")>
    <cfthrow type="Arguments" message="參數錯誤!!">
    </cfif>
    <!--- 實際檔案存在位置 --->
<cfset path = expandpath("/Downloads/Pictures")>
    <!--- 檢查檔案是否存在 --->
    <cfset fufile = path & "/" & file>
    <cfif not FileExists(fufile)>
    <cfthrow type="CHECK" message="檔案不存在!!">
    </cfif>
 
    <cffile action="readBinary" file="#fufile#" variable="data1">
 
<cfheader name="Content-Disposition" value="attachment; filename=""#file#""" />
    <cfcontent type="application/octet-stream; charset=big5" variable="#data1#" />
<cfcatch type="any">
 <!--- 發生錯誤時以網頁顯示 --->
 <cfcontent type="text/html" >
 <cfoutput>
  <html>
   <head>
    <meta http-equiv="Content-Type" content="text/html; charset=big5" />
   </head>
   <body>
    <div>
     Type = #cfcatch.Type#
    </div>
    <hr />
    <div>
    Message = #cfcatch.Message#
    </div>
   </body>
  </html>
 </cfoutput>
 <cfabort />
</cfcatch>
</cftry>



使用方式:

<a href="http://MySite.com/Download.cfm?file=2015-8-19  上午 10-42-36.png">

說明:

<cfif findnocase(CGI.SERVER_NAME,CGI.HTTP_REFERER) LTE 0>

這段是用來查驗使用者是否透過本伺服器的網頁正常聯結傳遞過來的。

當然也可以檢查 Cookie ,或是使用其他參數,檢查帳號等等....

<cfset path = expandpath("/Downloads/Pictures")>

實際檔案位置在使用者端看不到,避免直接盜連


<cfheader name="Content-Disposition" value="attachment; filename=""#file#""" />

這段可以強制瀏覽器以下載檔案方式處理,避免在瀏覽器上直接開啟。

<cfcontent type="application/octet-stream; charset=big5" variable="#data1#" />

由於下載時檔案種類繁多,無法一一去處理各種 Content Type 形態,所以直接以 octet-stream 來處理當成串流資料

留言

這個網誌中的熱門文章

【研究】列印的條碼為什麼很難刷(掃描)

C# 使用 Process.Start 執行外部程式

統一發票列印小程式