ajax跨域调用webservice的实现代码


Posted in Javascript onMay 09, 2016

最近ajax访问webservice遇到跨域的问题,网上搜索资料,总结如下(很多都是觉得人家总结不错的复制下来)

<<用JSON来传数据,靠JSONP来跨域>>

先上我的已实现代码:

前端代码:

$.ajax({
 type: "get",
 url: "http://localhost/Service1.asmx/getElevatorStatusJsonData?jsoncallback=?",
 dataType: "jsonp",
 jsonp: "json",
 data: "",
 success: function (result) {
 var data = eval(result);
 for (var i = 0; i < data.length; i++) {
 alert(data[i].ID + "--" + data[i].Name);
 }
 },
 error: function (a, b, c) {
 alert(c);
 }
 });

服务端代码:

/// <summary>
 /// 获取状态数据信息
 /// </summary>
 /// <returns></returns>
 [WebMethod]
 public void getElevatorStatusJsonData()
 {
 List<List<DeviceInfo>> elevatordatas = new List<List<DeviceInfo>>();
 List<SendDicdate> searchList = XmlSerializeHelper.XmlDeserializeFromFile<List<SendDicdate>>(@ConfigUtil.servicePath + ConfigUtil.getConfigByKey("xmlPath") + "查询指令信息.xml", Encoding.UTF8);
 foreach (SendDicdate item in searchList)
 {
 string key = item.portno + "-" + item.bordrate + "-" + item.sendtype;
 List<DeviceInfo> deviceInfoList = (List<DeviceInfo>)Context.Cache.Get(key);
 elevatordatas.Add(deviceInfoList);
 }

 String result = "";
 DataContractJsonSerializer json = new DataContractJsonSerializer(elevatordatas.GetType());
 using (MemoryStream stream = new MemoryStream())
 {
 json.WriteObject(stream, elevatordatas);
 result = Encoding.UTF8.GetString(stream.ToArray());
 }
 String jsoncallback = HttpContext.Current.Request["jsoncallback"];
 result = jsoncallback + '(' + result + ')';
 HttpContext.Current.Response.Write(result);
 HttpContext.Current.Response.End();

 }

c#

 以上是调用c#服务端的实现代码,下面的是java端的,参数可能有差异,但原理是相通的

java:

String callbackFunName = context.Request["callbackparam"];
context.Response.Write(callbackFunName + "([ { \"name\":\"John\"}])");

  PS:客户端的jsonp参数是用来通过url传参,传递jsonpCallback参数的参数名,比较拗口,通俗点讲:

jsonp: ""

jsonpCallback:""

顺带一提:在chrome浏览器里,还可以在服务端设置header信息context.Response.AddHeader("Access-Control-Allow-Origin", "*");来达到跨域请求的目的,并且不需要设置ajax以下参数

dataType : "jsonp",
jsonp: "callbackparam",

jsonpCallback:"jsonpCallback1"

以正常ajax请求方式就可以获得数据。

下面是原理,看别人讲解的,感觉很有道理:

1、一个众所周知的问题,Ajax直接请求普通文件存在跨域无权限访问的问题,甭管你是静态页面、动态网页、web服务、WCF,只要是跨域请求,一律不准;

2、不过我们又发现,Web页面上调用js文件时则不受是否跨域的影响(不仅如此,我们还发现凡是拥有”src”这个属性的标签都拥有跨域的能力,比如

3、于是可以判断,当前阶段如果想通过纯web端(ActiveX控件、服务端代理、属于未来的HTML5之Websocket等方式不算)跨域访问数据就只有一种可能,那就是在远程服务器上设法把数据装进js格式的文件里,供客户端调用和进一步处理;

4、恰巧我们已经知道有一种叫做JSON的纯字符数据格式可以简洁的描述复杂数据,更妙的是JSON还被js原生支持,所以在客户端几乎可以随心所欲的处理这种格式的数据;

5、这样子解决方案就呼之欲出了,web客户端通过与调用脚本一模一样的方式,来调用跨域服务器上动态生成的js格式文件(一般以JSON为后缀),显而易见,服务器之所以要动态生成JSON文件,目的就在于把客户端需要的数据装入进去。

6、客户端在对JSON文件调用成功之后,也就获得了自己所需的数据,剩下的就是按照自己需求进行处理和展现了,这种获取远程数据的方式看起来非常像AJAX,但其实并不一样。

7、为了便于客户端使用数据,逐渐形成了一种非正式传输协议,人们把它称作JSONP,该协议的一个要点就是允许用户传递一个callback 参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数 据了。

聪明的开发者很容易想到,只要服务端提供的js脚本是动态生成的就行了呗,这样调用者可以传一个参数过去告诉服务端“我想要一段调用XXX函数的js代码,请你返回给我”,于是服务器就可以按照客户端的需求来生成js脚本并响应了。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title></title><script type="text/javascript">// 得到航班信息查询结果后的回调函数var flightHandler =function(data){
 alert('你查询的航班结果是:piao价 '+ data.price +' 元,'+'余piao '+ data.tickets +' 张。');
 }; // 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码)var url ="http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler"; // 创建script标签,设置其属性var script = document.createElement('script');
 script.setAttribute('src', url); 
 // 把script标签加入head,此时调用开始 
//document.getElementsByTagName('head')[0].appendChild(script); 
</script></head><body></body></html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title>Untitled Page</title><script type="text/javascript" src=jquery.min.js"></script><script type="text/javascript">
 jQuery(document).ready(function(){
 $.ajax({
 type: "get",
 async: false,
 url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998",
 dataType: "jsonp",
 jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback) jsonpCallback:"flightHandler",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据 success: function(json){
 alert('您查询到航班信息:piao价: '+ json.price +' 元,余piao: '+ json.tickets +' 张。');
 },
 error: function(){
 alert('fail');
 }
 });
 }); </script></head><body></body></html>

是不是有点奇怪?为什么我这次没有写flightHandler这个函数呢?而且竟然也运行成功了!哈哈,这就是jQuery的功劳了,jquery在处理jsonp类型的ajax时(还是忍不住吐槽,虽然jquery也把jsonp归入了ajax,但其实它们真的不是一回事儿),自动帮你生成回调函数并把数据取出来供success属性方法来调用,是不是很爽呀?

Javascript 相关文章推荐
js页面跳转的问题(跳转到父页面、最外层页面、本页面)
Aug 14 Javascript
JavaScript中switch语句的用法详解
Jun 03 Javascript
jQuery 全选 全部选 反选 实现代码
Aug 17 Javascript
jQuery实现的自定义滚动条实例详解
Sep 20 Javascript
jQuery焦点图轮播效果实现方法
Dec 19 Javascript
Node.js中文件操作模块File System的详细介绍
Jan 05 Javascript
JavaScript实现瀑布流以及加载效果
Feb 11 Javascript
Vue源码学习之初始化模块init.js解析
Nov 02 Javascript
Angularjs过滤器实现动态搜索与排序功能示例
Dec 13 Javascript
vue项目国际化vue-i18n的安装使用教程
Mar 14 Javascript
element-ui 远程搜索组件el-select在项目中组件化的实现代码
Dec 04 Javascript
详解小程序横屏方案对比
Jun 28 Javascript
MVC+jQuery.Ajax异步实现增删改查和分页
Dec 22 #Javascript
基于Jquery插件Uploadify实现实时显示进度条上传图片
Mar 26 #Javascript
jQuery实现三级菜单的代码
May 09 #Javascript
Boostrap入门准备之border box
May 09 #Javascript
CKEditor无法验证的解决方案(js验证+jQuery Validate验证)
May 09 #Javascript
jQuery代码实现图片墙自动+手动淡入淡出切换效果
May 09 #Javascript
jQuery绑定事件的几种实现方式
May 09 #Javascript
You might like
一些常用的php简单命令代码集锦
2007/09/24 PHP
PHP访问MYSQL数据库封装类(附函数说明)
2010/12/04 PHP
使ecshop模板中可引用常量的实现方法
2011/06/02 PHP
PHP fclose函数用法总结
2019/02/15 PHP
PHP经典设计模式之依赖注入定义与用法详解
2019/05/21 PHP
thinkphp5.1框架中容器(Container)和门面(Facade)的实现方法分析
2019/08/05 PHP
Laravel5.1 框架Request请求操作常见用法实例分析
2020/01/04 PHP
silverlight线程与基于事件驱动javascript引擎(实现轨迹回放功能)
2011/08/09 Javascript
关于js日期转化为毫秒数“节省20%的效率和和节省9个字符“问题
2012/03/01 Javascript
判断js对象是否拥有某一个属性的js代码
2013/08/16 Javascript
基于jQuery的判断iPad、iPhone、Android是横屏还是竖屏的代码
2014/05/11 Javascript
js表头排序实现方法
2015/01/16 Javascript
JavaScript获取数组最小值和最大值的方法
2015/06/09 Javascript
jquery动态导航插件dynamicNav用法实例分析
2015/09/06 Javascript
AngularJs自定义服务之实现签名和加密
2016/08/02 Javascript
JavaScript中关于iframe滚动条的去除和保留
2016/11/17 Javascript
JavaScript实现向select下拉框中添加和删除元素的方法
2017/03/07 Javascript
解决JS外部文件中文注释出现乱码问题
2017/07/09 Javascript
详解关于element el-button使用$attrs的一个注意要点
2018/11/09 Javascript
[jQuery] 事件和动画详解
2019/03/05 jQuery
element跨分页操作选择详解
2020/06/29 Javascript
[04:04]显微镜下的DOTA2第六期——电影级别的华丽团战
2014/06/20 DOTA
paramiko模块安装和使用(远程登录服务器)
2014/01/27 Python
Python文件夹与文件的操作实现代码
2014/07/13 Python
Python实现Windows上气泡提醒效果的方法
2015/06/03 Python
深入理解Python中字典的键的使用
2015/08/19 Python
python中dict字典的查询键值对 遍历 排序 创建 访问 更新 删除基础操作方法
2018/09/13 Python
Python 200行代码实现一个滑动验证码过程详解
2019/07/11 Python
django中SMTP发送邮件配置详解
2019/07/19 Python
纯HTML+CSS3制作导航菜单(附源码)
2013/04/24 HTML / CSS
System.Array.CopyTo()和System.Array.Clone()有什么区别
2016/06/20 面试题
运动会通讯稿200字
2014/02/16 职场文书
村委会贫困证明范文
2014/09/21 职场文书
小型婚礼主持词
2015/06/30 职场文书
如何写一份具有法律效力的借款协议书?
2019/07/02 职场文书
MySQL查询日期时间
2022/05/15 MySQL