今天看到http://www.jq-school.com/ 首页中
当把鼠标放到每篇文章时,自动显示该文章的缩略内容,感到非常不错,
仔细看里面的源代码,里面只有以下类似的代码:
<div class="codelistp">
<a href="http://www.jq-school.com/Detail.aspx?id=64" pid="64" class="linkscroll" title="分享一款省市地区三级联动弹出层Jquery特效" target="_blank">分享一款省市地区三级联动弹出层Jquery特效</a>
…</div>
没找到是如何实现的,经过了1个多小时的研究,终于明白了它的实现原理;
原来在它的文件头里引入了一个JS文件
在 JS文件里有以下语句:
$(".codelistp a").hover(function() {
GetImage($(this).attr('pid'), $(this));
}, function() {
$("#showImg").hide();
});
给这css class=codelistp下的每个link定义了鼠标放上去时自动显示图片的方法;
function GetImage(id,obj){
var offset = obj.offset();;
$.ajax({
type: "post",
url: "GetImages.ashx?id="+id,
async: true,
data:null,
dataType:"html",
success:function(data){
//alert(data);
$("#showImg").html("<img src='"+data+"' />").css({ "left":offset.left+obj.width() , "top":offset.top }).show();
},
beforeSend:function(){
//正在请求中$("#load").show();
},
complete:function(){
//调用完成时$("#load").hide();
}
});
}
函数原型:$.post(url,params, callback)
url是提交的地址,eg: "sample.ashx"
params是参数,eg: { name:"xxx" , id:"001" }
callback是回调函数,eg: function(msg){ alert(msg); }
注意1:在sample.ashx那段,使用context.Request["id"]和context.Request["name"]来分别获得值"001"和值"xxx",而不是使用context.Request.QueryString["id"]
注意2:这里的callback里的函数是在服务器返回值后被触发,所以不需要另行判断xmlHttp.readyState==4 &&xmlHttp.status==200
至此明白了它的实现办法:利用ashx文件返回一个图片的地址,将图片内嵌到页面中隐藏的Div中,并显示该Div
以下是在文件的Form tag下的div
<div id="showImg" style="position:absolute; display:none;background:#fff url(images/farmebg.gif) repeat-x 0 0; border:1px solid #cacaca; margin-bottom:10px; overflow:hidden; z-index:999;"></div>
由于以往很少使用Ashx,以下是从网上抄过来实现的步骤:
.ashx是一个专门的用于处理HttpHandler的文件类型,用来处理自定义Http请求,可以在web.config定义运行时针对ashx的Http请求处理方式。
<add path="*.ashx" verb="*" type="System.Web.UI.SimpleHandlerFactory" validate="True" />
如果定义的ashx是一个单独的类库,可以用一下方法
<system.web>
<httpHandlers>
<remove verb="*" path="*.ashx" />
<add verb="*" path="*.ashx" type="GetImages,dll" />
</httpHandlers>
</system.web>
必须继承IHttpHandler
public class demoashx : IHttpHandler
{
... // todo somthing
}
实例:使用ashx+jQuery实现上图当鼠标指向一个link时 返回该link内容的图片的功能
.ashx文件
<%@ WebHandler Language="C#" Class="GetImages" %>
using System;
using System.Web;
public class GetImages : IHttpHandler {
public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "text/plain";
if (string.IsNullOrEmpty(context.Request["id"]))
{
//如果找不到则返回一个缺省的图片地址
context.Response.Write("/images/7.gif");
}
else
{
string imgID = context.Request["id"].ToString().Trim();
//从数据库获得该图片对应的Image 地址
//string sql = " select cid,rtrim(clientName) as [name] from clientInfo "
// + " where charindex('" + imgID + "',rtrim(clientName)) > 0 for xml auto,root('yoolo')";
string imgUrl = "/images/4.gif";
context.Response.Write(imgUrl);
}
context.Response.End();
}
public bool IsReusable {
get {
return false;
}
}
}
ashx文件的使用(转)
一提到Ashx文件,我们就会想到http handler以及图片加载(在之前我们一般使用ASPX或者Webservice去做),一般做法如下:
Handler.ashx:
<%@ WebHandler Language="C#" Class="Handler" %>
using System;
using System.IO;
using System.Web;
public class Handler : IHttpHandler {
public bool IsReusable {
get {
return true;
}
}
public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "image/jpeg";
context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.BufferOutput = false;
PhotoSize size;
switch (context.Request.QueryString["Size"]) {
case "S":
size = PhotoSize.Small;
break;
case "M":
size = PhotoSize.Medium;
break;
case "L":
size = PhotoSize.Large;
break;
default:
size = PhotoSize.Original;
break;
}
Int32 id = -1;
Stream stream = null;
if (context.Request.QueryString["PhotoID"] != null && context.Request.QueryString["PhotoID"] != "") {
id = Convert.ToInt32(context.Request.QueryString["PhotoID"]);
stream = PhotoManager.GetPhoto(id, size);
} else {
id = Convert.ToInt32(context.Request.QueryString["AlbumID"]);
stream = PhotoManager.GetFirstPhoto(id, size);
}
if (stream == null) stream = PhotoManager.GetPhoto(size);
const int buffersize = 1024 * 16;
byte[] buffer = new byte[buffersize];
int count = stream.Read(buffer, 0, buffersize);
while (count > 0) {
context.Response.OutputStream.Write(buffer, 0, count);
count = stream.Read(buffer, 0, buffersize);
}
}
}
*.aspx:
<img src="myHttpHander.ashx?id=123" width="20" height="20" />
我们变通以下,发现其实除了可以输出图片以外,还可以输出文字:
Handler.ashx:
<%@ WebHandler Language="C#" Class="Handler" %>
using System;
using System.Web;
public class Handler : IHttpHandler {
public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "text/plain";
context.Response.Write("alert('hi')");
}
public bool IsReusable {
get {
return false;
}
}
}
*.aspx:
弹出alert
<script src="Handler.ashx"></script>
也可以把.ashx当成css文件
<link href="css/Handler.ashx" rel="stylesheet" type="text/css">
xml文件
orderDoc.load("Handler.ashx");
还可以嵌入文字:
Handler.ashx:
<%@ WebHandler Language="C#" Class="TestHandler" %>
using System;
using System.Web;
public class TestHandler : IHttpHandler {
public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "text/plain";
context.Response.Write("document.write(\"Hello World\");");
}
public bool IsReusable {
get {
return false;
}
}
}
*.aspx:
<script type="text/javascript" src="TestHandler.ashx" />
当你希望从ashx或HttpHandler里访问你的Session时,你必须实现IReadOnlySessionState接口.
代码:
using System;
using System.Web;
using System.Web.SessionState;
public class DownloadHandler : IHttpHandler, IReadOnlySessionState
{
public bool IsReusable { get { return true; } }
public void ProcessRequest(HttpContext ctx)
{
ctx.Response.Write(ctx.Session["fred"]);
}
}
其实,学习的思路不应该这样,以上除了图片外,我们都用偏了,为什么用偏了呢,因为软件以简单、实用为主,我们只是把以上纯粹看成可一项技术而没有把它放到软件的地位去考虑:)
具体的用途,大家可以参考Rewirte.dll (这个dll,可以使服务器支持伪静态的)!
反编译,看看人家做的:)
使用HttpHandler实现图片防盗链
有了之前这么多的准备知识,实现现在的目标就容易得多了:
NOTE:这个例子,以及下面的一个例子均来自于《Maximizing ASP.NET Real World, Object-Oriented Development》一书:
Step.1:创建文件 CustomHandler.cs,代码如下:
using System;
using System.Web;
namespace CustomHandler{
public class JpgHandler : IHttpHandler{
public void ProcessRequest(HttpContext context){
// 获取文件服务器端物理路径
string FileName = context.Server.MapPath(context.Request.FilePath);
// 如果UrlReferrer为空,则显示一张默认的禁止盗链的图片
if (context.Request.UrlReferrer.Host == null){
context.Response.ContentType = "image/JPEG";
context.Response.WriteFile("/error.jpg");
}else{
// 如果 UrlReferrer中不包含自己站点主机域名,则显示一张默认的禁止盗链的图片
if (context.Request.UrlReferrer.Host.IndexOf("yourdomain.com") > 0){
context.Response.ContentType = "image/JPEG";
context.Response.WriteFile(FileName);
}else{
context.Response.ContentType = "image/JPEG";
context.Response.WriteFile("/error.jpg");
}
}
}
public bool IsReusable{
get{ return true; }
}
}
}
Step.2 编译这个文件
csc /t:library /r:System.Web.dll CustomHandler.cs
Step.3 将编译好的 CustomHandler.dll 拷贝到站点的 Bin 目录下。
Step.4 在Web.Config 中注册这个Handler。
<system.web>
<httpHandlers>
<add path="*.jpg" verb="*" type="CustomHandler.JpgHandler, CustomHandler" />
</httpHandlers>
</system.web>
OK,诸位可以按步骤自行测试一下,这里就不赘述了。