需求某網站因業務擴展需拆分出另一個站點新舊站點具有相同的內容但具體欄目表現形式上不一樣原網站運行多年有大量的圖片這些圖片也會在新站上使用任務是保證兩個網站圖片內容同步即原來的站點增加一個圖片新站點即可使用這個圖片
分析假設兩個站點的域名分別為/和/ 將圖片分別拷到兩台服務器以後上傳圖片同時上傳兩台服務器這種方法雖簡單但是占用巨大的磁盤空間而且維護麻煩
在/的頁面上直接寫/的引用這種方式類似圖片盜鏈但工作量也很大每加一個圖片都要改鏈接日後維護工作也很大
一台服務器保留圖片另外一台服務器通過IIS的網絡共享方式訪問圖片但開放文件共享對服務器的安全將構成威脅
剖析頁面運行原理
當浏覽器向IIS請求頁面時IIS會把請求轉交給ASPNET HTTP管道HTTP管道是一組被控對象(HTPPModel)這些對象按順序處理請求並把這些請求轉換成一般的HTML文本HTTP管道的入口是HttpRuntime類的實體HttpRuntime類實體從內存程序池中選擇一個HttpApplication對象HttpApplication的主要工作是尋找這樣的類實體(HttpHandler)使之能夠處理請求應用程序能在WebConfig裡對這個Http處理句柄映射列表進行重定義下列nfig中的句柄定義了jpg資源請求的處理句柄
<httphandlers>
<add verb=* path=*jpg type=HandlerTest/>
</httphandlers>
Verb列表可以是逗號分隔的HTTP謂詞列表(例如GETPUTPOST)也可以是通配符*path路徑屬性可以包含單個URL路徑或簡單的通配符字符串(例如*aspx)type指定逗號分隔的類/程序集組合ASPNET首先在應用程序的專用\bin目錄中搜索程序集DLL然後在系統程序集緩存中搜索程序集DLL
從代碼層面來看要實現自定義的HTTP處理句柄只需要實現一個IhttpHandler接口其中包括IsReusable和ProcessRequest兩個方法IsReusable方法用於返回應用程序池中是否存在可重用的類實體的信息利用這個方法可以同時為多個請求服務而ProcessRequest方法則接受一個HttpContext實體作為參數從而得到對Request和Response的存取權限
處理思路當對的請求到達IIS時ASPNET初始化一個圖像生成器類在這個類中通過HTTP端口把取回來再將圖像流返回到HTTP響應中接收並處理HTTP請求是在ProcessRequest方法中完成的客戶端並不知道實際發生了什麼事情
代碼
using System;
using SystemNet; using SystemIO; using SystemWeb; using SystemDrawing; using SystemDrawingImaging;
namespace WebHttpModule
{
public class ImageLink : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string url = contextRequestUrlToString(); //if request is / then changed to request / url = urlReplace(/ /);
//如果使用的相對路徑就要手工加入完整的url路徑if (urlIndexOf(/) <= )
{
url = / + url;
}
//create one WebClient object used to request the image of /
WebClient client = new WebClient();
Stream stream = clientOpenRead(url);
Image image = ImageFromStream(stream); contextResponseContentType = image/jpeg; //將圖像寫入HTTP響應返回給客戶端請求imageSave(contextResponseOutputStream ImageFormatJpeg);
imageDispose();
}
public bool IsReusable
{
get
{
return true;
}
}
}
}
配置
將上面的代碼編譯為ImageLinkdll在b服務器建立和a機器相同路徑的圖片目錄images並在其下建立bin目錄將ImageLinkdll拷進去在b服務器中吧images目錄設定為一個應用程序這樣才能針對此應用程序設定相應的程序映射(添加相應的擴展)以把jpg後綴的請求發送到ASPNET去處理
在WebConfig中配置代碼來設定httpHandlers我們現在要做的把對images目錄下的jpg文件的請求轉到ImageLink來處理因此最終的設定如下
<httphandlers>
<add verb=* path=images/*jpg type= WebHttpModuleImageLink ImageLink/>
</httphandlers>
將nfig拷到images目錄下
到此大工就告成了!所有對b服務器請求的jpg圖片都會從a機器取到在客戶端卻看不出來
From:http://tw.wingwit.com/Article/program/net/201311/12780.html