一般大家對小檔案的解決辦法是直接在服務端讀取檔案,然後輸出,這樣就避免了檔案地址的暴露,這是一種解決辦法。而我現在想說的是使用 TransmitFile 方法直接輸出檔案,但是這個方法對大檔案的支撐力度有多少,以及會帶來多大的效能開銷,我還沒有測試過,有興趣的朋友可以測試下,並發表評論。
好了,進入正題,一般對下載站,大家想到的就是流量的問題,所以自動就想到應該把檔案與程式碼分開部署。所以我給檔案單獨做了一個次層網域,我們就叫 file.xxx.com 吧。主網站網域名稱就是 www.xxx.com了,或者其他次層網域都行。
那第一步就是先要實現這2個網站之間的身分識別驗證共用了,比如登陸了主站後自動分站就實現登入了,那.Net的Forms身分識別驗證很容易的就能實現這個功能,底層思路其實就是共用Cookie的原理。第二部就是給檔案站做許可權過濾。下面我們給主站以及檔案站同時添加web.config。給他們加入相同的配置,Web.config主要配置代碼如下: 複製代碼 代碼如下:<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<connectionStrings>
</connectionStrings>
<appSettings>
</appSettings>
<system.web>
<authentication mode="Forms">
<forms loginUrl="~/Home/LogOn" defaultUrl="/" timeout="600" slidingExpiration="true" name="File" path="/" enableCrossAppRedirects="true"></forms>
</authentication> <httpCookies domain=".xxx.com"/>
<machineKey validationKey="AAA977D304FB289C182E00C710A099C9F92986DC25AD69F8" decryptionKey="AAA2B3F76A9359431E717CA8275EE72EEEDC70ED55152010" validation="SHA1"/>
</system.web>
<!--此節點只需加到檔案站下--> <system.webServer>
<handlers>
<add name="*.*" path="*.*" verb="*" type="Web.Handler.Download" />
</handlers>
</system.webServer>
</configuration>
以上設定檔針對跨域訪問的幾個關鍵配置點:一:authentication的name要相同,path="/" 表示cookie儲存路徑為根網域名稱,enableCrossAppRedirects="true" 表示身分識別驗證是否可以重新導向到其他應用程式。二:httpCookie節點配置為頂級網域名稱。三:兩個網站的machinekey必須相同。 那針對許可權控制,通過實現.Net裡面的訪問過濾器,也就是IHttpHandler介面,用來攔截訪問。實現方法也很簡單,只要實現ProcessRequest方法就可以了,下面是My Code: 複製代碼 代碼如下:namespace Web.Handler
{
/// <summary>
/// 檔案下載登陸驗證
/// </summary>
public class Download : IHttpHandler
{
public bool IsReusable
{
get
{
return true;
}
}
public void ProcessRequest(HttpContext context)
{
if (context.User.Identity.IsAuthenticated)
{
string fileName = context.Server.MapPath(context.Request.FilePath);
context.Response.ContentType = Path.GetExtension(fileName);
context.Response.TransmitFile(context.Request.FilePath);
}
else
{
context.Response.Write("您未登入!");
}
}
}
}
寫完以上代碼後,那就是增加過濾配置了,注意上面的設定檔注釋,最主要的配置節:<add name="*.*" path="*.*" verb="*" type="Web.Handler.Download" /> name是篩選器的名稱,隨便填,path表示你要過濾的檔案尾碼,我是所有檔案都需要過濾,所以直接用*.*,如果單純只過濾jpg跟gif,可以改為:*.jpg,*.gif 即可,type表示過濾器Dll地址,也就是我們實現IHttpHandler的類全名,ok,檔案存取控制就已經完成了。 注意:由於我使用的是IIS7,所以此處的Handler添加到了system.webSever節點下,IIS6及以下版本直接添加到system.web節點下就可以了。