using System; using System.IO; using System.Web; /// <summary> /// 说明:DownloadHandlerReferrer是一个防盗链的类,它可以防止本站资源被别的网站盗用 /// 该源码来自 周公 《Asp.Net夜话》,转载请注明,Thank you :-) /// </summary> public class DownloadHandlerReferrer:IHttpHandler { public DownloadHandlerReferrer() { } #region IHttpHandler 成员 /// <summary> /// 指示IHttpHandler 实例是否可再次使用 /// </summary> public bool IsReusable { get { return true; } } /// <summary> /// 处理请求的方法 /// </summary> /// <param name="context">它提供对用于为 HTTP 请求提供服务的内部服务器对象(如 Request、Response、Session 和 Server)的引用。</param> public void ProcessRequest(HttpContext context) { HttpRequest request=context.Request; HttpResponse response=context.Response; Uri referrerUri = request.UrlReferrer;//获取下载之前访问的那个页面的uri Uri currentUri = request.Url; string path = request.PhysicalPath;//获取客户端请求的文件的物理地址 if (referrerUri == null)//没有前导页,直接访问下载页 { //输出提示,可以根据自身要求完善此处代码 response.Write("<br>请不要盗链本站资源,请从首页访问。<a href="index.aspx" mce_href="index.aspx">首页</a>"); return; } else { if (!File.Exists(path))//如果文件不存在,给出错误提示 { response.Write("请求的文件不存在,请从首页访问。<a href="index.aspx" >首页</a>"); return; } else { #region 判断前导页是否是我们的介绍页面 string referrerPage = referrerUri.LocalPath.Substring(referrerUri.LocalPath.LastIndexOf('/') + 1); if (referrerPage.StartsWith("Download.aspx"))//如果前导页是我们的介绍页面 { //用户是通过正常路径访问的,向用户提供下载文件 //实际情况是根据id从数据库找到文件的物理路径,然后输出 //为了简单代码,仅仅演示流程,这里我直接输出了文件 //获取请求的物理文件路径 WriteFile(path,response); } else { //输出提示,可以根据自身要求完善此处代码 response.Write("referrerPage="+referrerPage+"请不要盗链本站资源,请从首页访问。<a href="index.aspx" >首页</a>"); } #endregion } } } /// <summary> /// 输出文件内容 /// </summary> /// <param name="filePath">带全路径的文件名</param> private void WriteFile(string filePath,HttpResponse response) { //注意这里rar文件的ContentType是application/octet-stream //不同格式文件的contentType有可能不同 string extension=Path.GetExtension(filePath); //设置ContentType属性 response.ContentType =GetMimeType( extension); //获取不带路径的文件名 string fileName = System.IO.Path.GetFileName(filePath); //通过下面的设置保证会在用户浏览器出现下载提示而不是在当前浏览器打开 //Content-Disposition:文件内容描述 //attachment:表示作为附件发送到客户端,客户端将单独打开此文件 //filename:发送到客户端文件的文件名 response.AddHeader("Content-Disposition", "attachment;filename=" + fileName); response.WriteFile(filePath); } #endregion /// <summary> /// 根据文件后缀来获取MIME类型字符串 /// </summary> /// <param name="extension">文件后缀</param> /// <returns></returns> public static string GetMimeType(string extension) { string mime = string.Empty; extension = extension.ToLower(); switch (extension) { case ".avi": mime = "video/x-msvideo"; break; case ".bin": mime = "application/octet-stream"; break; case ".exe": mime = "application/octet-stream"; break; case ".dll": mime = "application/octet-stream"; break; case ".class": mime = "application/octet-stream"; break; case ".csv": mime = "text/comma-separated-values"; break; case ".css": mime = "text/css"; break; case ".doc": mime = "application/msword"; break; case ".dot": mime = "application/msword"; break; case ".gz": mime = "application/gzip"; break; case ".gif": mime = "image/gif"; break; case ".jpeg": mime = "image/jpeg"; break; case ".jpg": mime = "image/jpeg"; break; case ".jpe": mime = "image/jpeg"; break; case ".mpeg": mime = "video/mpeg"; break; case ".mpg": mime = "video/mpeg"; break; case ".mpe": mime = "video/mpeg"; break; case ".mp3": mime = "audio/mpeg"; break; case ".pdf": mime = "application/pdf"; break; case ".rar": mime = "application/octet-stream"; break; case ".txt": mime = "text/plain"; break; case ".xls": mime = "application/msexcel"; break; case ".xla": mime = "application/msexcel"; break; case ".z": mime = "application/x-compress"; break; case ".zip": mime = "application/x-zip-compressed"; break; default: break; } return mime; } } //webconfig里对应的修改如下: <location path="day12/download"> <system.web> <httpHandlers> <add path="WebResource.axd" verb="GET" type="System.Web.Handlers.AssemblyResourceLoader" validate="True" /> <add verb="*" path="*.*" type="DownloadHandlerReferrer"/> <!--<add verb="*" path="*.*" type="ForbiddenThief"/>--> </httpHandlers> </system.web> </location> 配合IIS中的映射使用。