注:Ajax技术出现之前,其中应用最广泛的技术是隐藏框架和远程脚本,隐藏框架利用了<frame>或者<iframe>元素,创建一个可用JavaScript与服务器通信的框架(0像素高<frame>或者隐藏的<iframe>元素)。
代码:
隐藏框架:
<!DOCTYPE> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Hidden Frame</title> <link href="Styles/upfile.css" rel="stylesheet" type="text/css" /> </head> <body> <form id="upFile" action="uploadHandler.ashx" method="post" target="iframe" enctype="multipart/form-data"> <input id="upload" name="upload" type="file" /> <input type="submit" /> </form> <iframe id="iframe" name="iframe" style="display:none;"> </iframe> <script type="text/javascript"> function Fn_CallBack() { alert("上传成功!"); } </script> </body> </html>
核心:将form的target="iframe" 指向iframe框架 并且iframe的css 设置为display:none 这样就隐藏了上传文件的刷新的过程,其实还是在刷新 只是感觉不到而已。
后台服务器保存图片,输出JS(JS 名称对应的就是上面定义好的(Fn_CallBack 名称)
public void ProcessRequest(HttpContext context) { HttpPostedFile file = context.Request.Files["upload"];//upload要和html type="file" 一致 string filePath = System.Web.HttpContext.Current.Server.MapPath("~/file"); file.SaveAs(filePath+"/"+file.FileName); string script = "<script>parent.Fn_CallBack()</script>"; context.Response.Write(script); } public bool IsReusable { get { return false; } }
远程脚本:(比较网上的一些jq插件 也是用的此原理)
动态创建script标签 利用scr指向服务器的 这样就具备了跨域的能力 同样 如果iframe的 url指向其他地方也具备了跨域的能力,但是远程脚本效率高,
缺点不能传送二进制文件。
代码:
<!DOCTYPE> <html> <head> <title>remote script</title> <style type="text/css"> body { font-size: 20px 20px 20px 20px; font-family: Tahoma; font-size: 14px; } </style> </head> <body> <form action="#"> 输入你的名字: <input id="userName" name="userName" type="text" /> <input type="button" value="发送" onclick="send()" /> </form> <script type="text/javascript"> function send() { var result; var msg = encodeURIComponent($("userName").value); //编码encodeURIComponent var script = document.createElement("script"); //创建script元素 script.src = "Script.ashx?msg=" + msg; //设置script的 scr属性 document.getElementsByTagName("head")[0].appendChild(script); //将script元素附加到页面dom树中 setTimeout(function () { alert(result); },5000); } function hadleResult(msg) { alert(msg); } function $(element) { if (typeof element == "string") { return document.getElementById(element); } else { return element; } } function removejscssfile(filename, filetype) { //判断文件类型 var targetelement = (filetype == "js") ? "script" : (filetype == "css") ? "link" : "none"; //判断文件名 var targetattr = (filetype == "js") ? "src" : (filetype == "css") ? "href" : "none"; var allsuspects = document.getElementsByTagName(targetelement); //遍历元素, 并删除匹配的元素 for (var i = allsuspects.length; i >= 0; i--) { if (allsuspects[i] && allsuspects[i].getAttribute(targetattr) != null && allsuspects[i].getAttribute(targetattr).indexOf(filename) != -1) allsuspects[i].parentNode.removeChild(allsuspects[i]); } } </script> </body> </html>
Script的代码:
public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/javascript"; string msg = context.Request.QueryString["msg"]; if (msg == null) msg = ""; string script = "result='hello," + msg + "!';hadleResult(result);$('userName').value=''; removejscssfile('Script.ashx', 'js'); "; context.Response.Write(script); } public bool IsReusable { get { return false; } }
问题在利用定时器判断result是否存在(目的保证script的ulr指向的服务器运行成功!)后访问result 为未定义?求解 看了回来好看看那个人的script来解决的跨域的问题。
附件jquery jsonp 代码(参考中国开源社区):
后台:
[WebMethod] [ScriptMethod(ResponseFormat = ResponseFormat.Json, XmlSerializeString = false, UseHttpGet = true)] public void Login(string userName, string userPwd, string macAddress) { var response = HttpContext.Current.Response; var context = HttpContext.Current.Request; response.Clear(); //清空无关信息 response.Buffer = true; //完成整个响应后再发送 response.Charset = "GB2312";//设置输出流的字符集-中文 response.AppendHeader("Content-Disposition", "attachment;filename=Report.doc");//追加头信息 response.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312");//设置输出流的字符集 response.ContentType = "text/json"; //获取回调函数名 string callback = context.QueryString["callback"]; var jsons = "[{\"taskId\": \"100\",\"projectName\": \"张三\" }]"; response.Write(callback + "(" + jsons + ")"); response.End(); }
前台:
$(function () { $("#jsonp_btn").click(function () { $.ajax({ async:false, url: 'http://localhost:82/Email.asmx/Login', // 跨域URL dataType: 'jsonp', jsonpCallback: 'persons', //默认callback data: {"userName":"admin","userPwd":"etimes2011@","macAddress":""}, //请求数据 timeout: 5000, beforeSend: function(){ //jsonp 方式此方法不被触发。原因可能是dataType如果指定为jsonp的话,就已经不是ajax事件了 }, success:function(data) { //客户端jquery预先定义好的callback函数,成功获取跨域服务器上的json数据后,会动态执行这个callback函数 alert("success "+data[0].projectName); }, complete: function(XMLHttpRequest, textStatus){ }, error: function(xhr){ //jsonp 方式此方法不被触发 //请求出错处理 alert("请求出错(请检查相关度网络状况.)"); } }); }); });