Asp.net MVC防止图片盗链的实现方法,通过自定义RouteHandler来操作
本文告訴你如何在ASP.NET MVC中實現一個自定義RouteHandler來防止其他人盜鏈你的圖片.
首先,我們來回顧一下當一個請求發往ASP.net MVC站點時的情景,IIS收到請求并將請求轉到ASP.net,然后根據URL,或者更確切來說:被請求文件的擴展名.在IIS7 integrated模式下(默認模式),所有的請求都會匹配到ASP.net中,而在IIS6中,你可以通過通配符來達到和IIS7相同的效果.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
在ASP.NET MVC程序中首先涉及的部件是UrlRoutingModule,它是System.Web.Routing的一部分.UrlRoutingModule用于第一次檢查請求的url和本地磁盤中的文件是否相匹配。如果匹配,UrlRoutingModule會將請求直接回發給IIS,IIS根據地址來進行相應。如果UrlRoutingModule沒有在磁盤中找到匹配的文件。它會檢查RouteCollection結構來決定是否繼續傳遞請求.UrlRoutingModule會引入RouteHandler和匹配的路徑入口(默認情況下是MvcRouteHandler)。而后會引入合適的HttpHandler來處理和請求有關的邏輯。默認情況下,這個HttpHandler會是MvcHandler.而對于圖片文件,一般會存在于程序中的某個子目錄中,核心的routeModule并沒有這種能力因為直接索取圖片的url回優先回發給iis,而流程在這時無法執行到RouteHandler被引入.
?
通常情況下,通過Asp.net取出磁盤上的靜態文件都是可以的。然而,如果你想執行一些業務邏輯而不是直接讓這類文件響應請求。你需要在某些關鍵點以編程的方式實現。你可以通過設置RouteTable.Routes.RouteExistingFiles = true來避免對現有文件的默認相應行為。Phil Haack( ASP.NET MVC的高級程序經理)稱之為”核武器級別的選項”,無論是css,js,doc,pdf等文件,在這種模式下所有文件都需要利用Routing來處理。所以確保這一點的關鍵是對于靜態文件的請求不能和磁盤上對應的文件匹配。這會強制RouteModule來對Route表(當然會引入RouteHandler等過程)進行查找。這很容易做,只需要讓<img>元素指向一個虛構的目錄即可。比如說,你的圖片是存放在網站根目錄下的images文件夾下,而<img>元素指向一個”graphics”文件夾將不會和存在的文件相匹配。
想做到這些,需要做如下:
為對于圖片的請求注冊Route
創建RouteHandler來處理這類請求
創建HttpHandler來處理實際的請求
我們首先從步驟2開始,因為如果沒有創建RouteHandler卻要在路由表中進行注冊的話,這不會編譯成功的.
RouteHandler很簡單,它是IRouteHandler的實現,它只有一個方法--IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext):
?
public class ImageRouteHandler : IRouteHandler{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
return new ImageHandler(requestContext);
}
}
對于實際的HttpHandler:
public class ImageHandler : IHttpHandler
{
public ImageHandler(RequestContext context)
{
ProcessRequest(context);
}
private static void ProcessRequest(RequestContext requestContext)
{
var response = requestContext.HttpContext.Response;
var request = requestContext.HttpContext.Request;
var server = requestContext.HttpContext.Server;
var validRequestFile = requestContext.RouteData.Values["filename"].ToString();
const string invalidRequestFile = "thief.gif";
var path = server.MapPath("~/graphics/");
response.Clear();
response.ContentType = GetContentType(request.Url.ToString());
if (request.ServerVariables["HTTP_REFERER"] != null &&
request.ServerVariables["HTTP_REFERER"].Contains("mikesdotnetting.com"))
{
response.TransmitFile(path + validRequestFile);
}
else
{
response.TransmitFile(path + invalidRequestFile);
}
response.End();
}
private static string GetContentType(string url)
{
switch (Path.GetExtension(url))
{
case ".gif":
return "Image/gif";
case ".jpg":
return "Image/jpeg";
case ".png":
return "Image/png";
default:
break;
}
return null;
}
public void ProcessRequest(HttpContext context)
{
}
public bool IsReusable
{
get { return false; }
}
} ?在上面代碼中,IHttpHandler中的ProcessRequest,有兩個重載,第一個是public void ProcessRequest(HttpContext context),在這里我們忽略這個重載,在MVC程序中,我們傳入RequestContext對象作為參數,而不是HttpContext對象。ProcessRequest方法會在ImageHandler的構造器中進行調用,在上面代碼中,ProcessRequest會首先檢查請求圖片的地址是否輸入我的域(也就是引用圖片的網頁是我的網站而不是其它人的),如果不是的話,則返回一張其它圖片。返回什么樣的圖片取決于你自己,我看到過很多種這樣的圖片,有些包含不和諧內容.甚至你可以返回一個1px的透明gif,或者可以使404 not found….
當然,在這點上你還可以采取一些其它步驟,比如說,你當然會希望google索引你的圖片,所以如果引用的鏈接包含”images.google”你可以返回真實圖片。你也可以在其它網站盜鏈你圖片不成功的情況下來用日志進行記錄.
?
最后一步要做的是為對圖片的請求注冊到RouteTable,用于表示ImageRouteHandler來對這部分請求進行處理,在global.axax文件中,加入:
routes.Add("ImagesRoute",
new Route("images/{filename}", new ImageRouteHandler())); 希望這篇文章不僅可以幫助你阻止那些盜鏈的吸血鬼,還能讓你對Asp.net MVC的底層有更深入的了解以便于你以后再有其他需求時可以進行擴展。
?
轉自:http://www.xueit.com/asp.net/show-5357-1.aspx
?
?
?
總結
以上是生活随笔為你收集整理的Asp.net MVC防止图片盗链的实现方法,通过自定义RouteHandler来操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PLC項目任務單2---狀態轉移圖
- 下一篇: jquery easy drag