ScriptTagProxy+XTemplate+WCF跨域取数据
小编:管理员 508阅读 2022.09.07
ajax应用中跨域一直是一个非常麻烦的问题,目前也有一些解决办法,但要么比较麻烦,要么就不具备通用性,幸好ExtJs里的ScriptTagProxy提供了跨域读取数据的功能,而且在几大浏览器上都可以正常运行,但在使用过程中要注意几点:
1.服务端返回时,必须按以下格式返回:
stcCallback1001({...})
其中stcCallback1001中的1001是自动生成的,如果是分页提交的话,每再请求一次1001会变成1002,1003...类推
2.ExtJs官方的示例中虽然ScriptTagProxy的例子并不少,但是就是没有XTemplate+ScriptTagProxy跨域读取的单一功能示例,下面给一个XTemplate跨域读取数据的示例
a.服务端WCF的处理
Code [OperationContract] [WebInvoke(ResponseFormat = WebMessageFormat.Json, UriTemplate = "GetData3?start={start}&limit={limit}&callback={callback}", Method = "*")] public Stream GetData3(int start, int limit,string CallBack) { System.Threading.Thread.Sleep(1000);//为演示Ajax加载效果,停1秒 List复制_List = new List (); _List.Add(new T_GuestBook() { F_ID = 1, F_IP = "192.23.37.41", F_Date = DateTime.Now, F_Content = "这是第一条留言", F_Reply = "" }); _List.Add(new T_GuestBook() { F_ID = 2, F_IP = "192.168.0.1", F_Date = DateTime.Now, F_Content = "这是第二条留言", F_Reply = "" }); _List.Add(new T_GuestBook() { F_ID = 3, F_IP = "192.168.0.2", F_Date = DateTime.Now, F_Content = "这是第三条留言", F_Reply = "" }); _List.Add(new T_GuestBook() { F_ID = 4, F_IP = "172.168.235.1", F_Date = DateTime.Now, F_Content = "这是第四条留言", F_Reply = "" }); _List.Add(new T_GuestBook() { F_ID = 5, F_IP = "10.200.30.4", F_Date = DateTime.Now, F_Content = "这是第五条留言", F_Reply = "" }); _List.Add(new T_GuestBook() { F_ID = 6, F_IP = "10.200.30.5", F_Date = DateTime.Now, F_Content = "这是第六条留言", F_Reply = "" }); //以上操作也可以改为利用Linq直接从数据库读取 PageData > _PageData = new PageData
>(); _PageData.RecordCount = _List.Count; int PageSize = limit; if (PageSize <= 0) { PageSize = 1; } if (PageSize > _PageData.RecordCount) { PageSize = _PageData.RecordCount; } _PageData.PageSize = PageSize; //计算总页数 if (_PageData.RecordCount % _PageData.PageSize == 0) { _PageData.PageCount = (_PageData.RecordCount / _PageData.PageSize); } else { _PageData.PageCount = (_PageData.RecordCount / _PageData.PageSize) + 1; } int PageIndex = (start/limit) + 1; if (PageIndex <= 0) { PageIndex = 1; } if (PageIndex > _PageData.PageCount) { PageIndex = _PageData.PageCount; } _PageData.CurrentPageIndex = PageIndex; List
_List2 = _List.Skip(start).Take(limit).ToList();//取得当前页数据 _PageData.Data = _List2; string returnStr = CallBack + "(" + JavaScriptConvert.SerializeObject(_PageData) +")"; MemoryStream ms = new MemoryStream(); StreamWriter sw = new StreamWriter(ms); sw.AutoFlush = true; sw.Write(returnStr); ms.Position = 0; WebOperationContext.Current.OutgoingResponse.ContentType = "text/plain"; return ms; }
这里与上一篇http://www.cnblogs.com/yjmyzz/archive/2008/09/10/1288399.html (ExtJs学习笔记(22)-XTemplate + WCF 打造无刷新数据分页)相比,多了一个参数callBack,同时返回类型改为Stream,返回方法的处理参考了老张的(再说ExtJs与WCF之间的跨域访问)一文
b.ExtJs的前端处理
Code复制
这里要注意的是:
尝试了多次,发现XTemplate不支持多层节点的绑定,即服务端返回的值类似:
stcCallback1001({"RecordCount":6,"PageSize":2,"PageCount":3,"CurrentPageIndex":2,"Data":[{"F_ID":3,"F_IP":"192.168.0.2","F_Date":new Date(1221399073843),"F_Content":"这是第三条留言","F_Reply":""},{"F_ID":4,"F_IP":"172.168.235.1","F_Date":new Date(1221399073843),"F_Content":"这是第四条留言","F_Reply":""}]})
在回调函数里经过Ext.util.JSON.encode(data)处理后,变成了
{"success":true,"records":[{"id":1001,"data":{"F_ID":3,"F_IP":"192.168.0.2","F_Date":"2008-09-14T21:28:28","F_Content":"这是第三条留言"},"json":
{"F_ID":3,"F_IP":"192.168.0.2","F_Date":"2008-09-14T21:28:28","F_Content":"这是第三条留言","F_Reply":""}},{"id":1002,"data":{"F_ID":4,"F_IP":"172.168.235.1","F_Date":"2008
-09-14T21:28:28","F_Content":"这是第四条留言"},"json":{"F_ID":4,"F_IP":"172.168.235.1","F_Date":"2008-09-14T21:28:28","F_Content":"这是第四条留
言","F_Reply":""}}],"totalRecords":6}
虽然也是标准的JSON字符串,但是数据节点是多层次的,XTemplate无法直接读取。所以只能在客户端用JS的正则表达式处理,手动重新组织成XTemplate所需的JSON对象,最终转换成:
{data:[{"F_ID":3,"F_IP":"192.168.0.2","F_Date":"2008-09-14T21:29:55","F_Content":"这是第三条留言","F_Reply":""},{"F_ID":4,"F_IP":"172.168.235.1","F_Date":"2008-09-14T21:29:55","F_Content":"这是第四条留言","F_Reply":""}]}
相关推荐
- ExtJs七(ExtJs Mvc创建ViewPort) 前言在4.1的时候,要先创建一个扩展于Ext.app.Application的类,然后用create创建它的实例来开始应用程序的。而在4.1.1,则可直接调用application方法开始执行应用程序,简化了。调用application方法,其参数是一个配置对象,主要配置项有以下三个:name:用来…
- 3DMAX提示和技巧 本主题标识使用 Civil View 的一些重要提示和技巧。常规使用屏幕分辨率至少为 1280x1024 的 Civil View。低于此分辨率时,一些面板将占用过多屏幕空间。 将视口设置为线框显示以达到最佳性能。 要尽可能简化用户界面,请在单个视口中工作并关闭 3ds Max 命令面…