HttpHandler对象实现防盗链
在实现图片的防盗链之前先介绍下Httpmodule和HttpHandler对象
对于Http请求而言,HttpModule是Http请求的“必经之路”,它可以在该HTTP请求传递到最终的“请求处理中心(HttpHandler)”进行处理之前做一些额外工作,或者在某些情况下终止满足一些条件的HTTP请求,从而起到一个过滤器的作用。HttpModule有多个,每次HTTP请求都将逐一通过每个HTTPmodule。HTTPmodule和httpApplication对象是直接交互的。
创建一个HttpModule类
namespace Example1
{
public class TestHttpModule:HttpModule
{
public void Dispose()
{
throw new NotlmplementedException();
}
public void Init(HttpApplication context)
{
//初始化,为HttpApplication对象绑定两个事件
//在HttpHandler请求处理之前触发的事件
context.BeginRequest += context_BeginRequest;
//请求处理完毕后触发的事件
context.EndRequest+= context_EndRequest;
}
//在请求处理之前,附加信息
private void context_BeginRequest(object sender,EventArgs e)
{
HttpApplication application = sender as HttpApplication;
application.Response.Write("<p>HttpModule开始处理请求</P>");
}
//在请求处理完毕后,附加信息
private void context_EndRequest(object sender,EventArgs e)
{
HttpApplication application = sender as HttpApplication;
application.Response.Write("<p>HttpModule结束处理请求</P>");
}
}
}
配置配置信息,实现了HttpModule类,还需要在Web.config中配置,在节点下添加如下内容
<system.webServer>
<modules>
<add name="test" type="Example1.TestHttpModule"/>
</modules>
</system.webServer>
最后创建两个ASP.NET页面的源文件中,分别在各自的标签下添加
标签。
第一个页面:
欢迎访问页面1
第二个页面:
欢迎访问页面2
当访问动态页面时,ASP.NET会创建HttpApplication类的实例,同时会创建所有在Web.config中注册过的HttpModule实例,在创建HttpModule实例时会调用Init()方法,绑定HttpApplication对象的BeginRequest和EndRequest事件的处理方法。HttpApplication对象的BeginRequest事件最先触发,EndRequest事件最后触发。
HttpApplication对象的属性包括Request、Response、Server和Session等。
注意
验证HttpModule是每个动态页面请求的必经之路,即所有动态页面请求必须以此通过所有的HttpModule。
ASP.NET中也内置了HttpModule类,如用于进行页面状态管理的Session类、用于缓存页面的OutputCache类等。
HttpHandler对象的概述与使用
通过上述知识点,了解每个Http请求都可能经过多个HttpModule处理,然而最终的处理中心是HttpHandler如果说HttpModule负责所有请求的初始化和请求收尾等工作,那么HttpHandler则负责具体工作,它是每一个请求的处理中心。
HttpHandler对象实现防盗链
演示防盗链需求:
如下
- 创建一个网站,网站的Images文件夹中又Jpg图片资源,本网站的页面引用图片的相对路径后可以正常显示
- 创建第二个网站,网站下有一个页面引用了上一个网站的Jpg图片资源,结果不能正常显示图片资源,而会显示一个表示错误的图片。
在IIS中部署第一个网站效果如下
<img src="images/动漫1.png"/>
<img src="images/动漫2.png"/>
<img src="images/动漫3.png"/>
创建盗链接站点。创建第二个网站添加ASPX页面引用第一个网站的三幅图片,如下:
<p>以下图片来着第一个站点</p>
<img src="http://localhost:49420/images/%E5%8A%A8%E6%BC%AB1.png"/>
<img src="http://localhost:49420/images/%E5%8A%A8%E6%BC%AB2.png"/>
<img src="http://localhost:49420/images/%E5%8A%A8%E6%BC%AB3.png" />
第二个站点会显示第一个站点的图片
在第一个站点创建一个类
输入代码如下
public class Handler1 : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
//获取上次请求的URL
Uri lastUrl = context.Request.UrlReferrer;
//获取本次请求的URL
Uri currentUrl = context.Request.Url;
//判断是否为盗链
if (lastUrl.Host != currentUrl.Host || lastUrl.Port != currentUrl.Port)
{
//获取“请勿盗链”警告提示图片路径
string errorImagePath = context.Request.PhysicalApplicationPath + "images/像素赛博朋克.png";
//发送至客户端
context.Response.WriteFile(errorImagePath);
}
else
{
context.Response.WriteFile(context.Request.PhysicalPath);
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
配置相关配置文件,代码如下
<system.webServer>
<handlers>
<add verb="*" path="images/*.png" type="WebApplication3.Handler1" name="plink"/>
</handlers>
</system.webServer>
则第二个站点显示的图片如下:
添加水印
图片添加水印可以极大的增加安全性
添加一个webform
<style>
#Image1{
width:500px;
height:500px;
}
#Image2{
width:500px;
height:500px;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Image ID="Image1" runat="server" ImageUrl="~/Images/02.jpg" />
<asp:Image ID="Image2" runat="server" ImageUrl="~/Images/03.jpg" />
</div>
在网站中添加HttpHandler类,继承IHttpHandler接口,编写加水印功能
public class TestHandel : IHttpHandler
{
private const string WATERMARK_URL = "~/Images/01.jpg";
private const string DEFAULTIME_URL = "~/Error/04.jpg";
public bool IsReusable
{
get
{
return false;
}
}
public void ProcessRequest(HttpContext context)
{
string filePath = context.Request.PhysicalPath;
System.Drawing.Image Cover;
if (File.Exists(filePath))
{
Cover = Image.FromFile(filePath);
Image watermark = Image.FromFile(context.Server.MapPath(WATERMARK_URL));
Graphics G = Graphics.FromImage(Cover);
G.DrawImage(watermark, new Rectangle(Cover.Width - watermark.Width,
Cover.Height - watermark.Height, watermark.Width, watermark.Height), 0,
0, watermark.Width, watermark.Height, GraphicsUnit.Pixel);
G.Dispose();
watermark.Dispose();
}
else
{
Cover = Image.FromFile(context.Request.MapPath(DEFAULTIME_URL));
}
context.Response.ContentType = "Images/jpeg";
Cover.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);
Cover.Dispose();
context.Response.End();
}
}