jQuery 跨域访问问题解决方法


Posted in Javascript onDecember 02, 2009

时间过得好快,又被拉回js战场时, 跨域问题这个伤疤又开疼了.

好在,有jquery帮忙,跨域问题似乎没那么难缠了.这次也借此机会对跨域问题来给刨根问底,结合实际的开发项目,查阅了相关资料,算是解决了跨域问题..有必要记下来备忘.

跨域的安全限制都是指浏览器端来说的.服务器端是不存在跨域安全限制的,
所以通过本机服务器端通过类似httpclient方式完成“跨域访问”的工作,然后在浏览器端用AJAX获取本机服务器端“跨域访问”对应的url.来间接完成跨域访问也是可以的.但很显然开发量比较大,但限制也最少,很多widget开放平台server端(如sohu博客开放平台)其实就么搞的.不在本次讨论范围.

要讨论的是浏览器端的真正跨域访问,推荐的是目前jQuery $.ajax()支持get方式的跨域,这其实是采用jsonp的方式来完成的.

真实案例:

var qsData = {'searchWord':$("#searchWord").attr("value"),'currentUserId':$("#currentUserId").attr("value"),'conditionBean.pageSize':$("#pageSize").attr("value")}; $.ajax({ 
async:false, 
url: http://跨域的dns/document!searchJSONResult.action, 
type: "GET", 
dataType: 'jsonp', 
jsonp: 'jsoncallback', 
data: qsData, 
timeout: 5000, 
beforeSend: function(){ 
//jsonp 方式此方法不被触发.原因可能是dataType如果指定为jsonp的话,就已经不是ajax事件了 
}, 
success: function (json) {//客户端jquery预先定义好的callback函数,成功获取跨域服务器上的json数据后,会动态执行这个callback函数 
if(json.actionErrors.length!=0){ 
alert(json.actionErrors); 
} 
genDynamicContent(qsData,type,json); 
}, 
complete: function(XMLHttpRequest, textStatus){ 
$.unblockUI({ fadeOut: 10 }); 
}, 
error: function(xhr){ 
//jsonp 方式此方法不被触发.原因可能是dataType如果指定为jsonp的话,就已经不是ajax事件了 
//请求出错处理 
alert("请求出错(请检查相关度网络状况.)"); 
} 
});

注意:$.getJSON(" http://跨域的dns/document!searchJSONResult.action?name1="+value1+"&jsoncallback=?",
function(json){
if(json.属性名==值){
// 执行代码
}
});
这种方式其实是上例$.ajax({..}) api的一种高级封装,有些$.ajax api底层的参数就被封装而不可见了.
这样,jquery就会拼装成如下的url get请求
http://跨域的dns/document!searchJSONResult.action?&jsoncallback=jsonp1236827957501&_=1236828192549&searchWord=%E7%94%A8%E4%BE%8B¤tUserId=5351&conditionBean.pageSize=15

在响应端(http://跨域的dns/document!searchJSONResult.action),
通过 jsoncallback = request.getParameter("jsoncallback") 得到jquery端随后要回调的js function name:jsonp1236827957501
然后 response的内容为一个Script Tags:"jsonp1236827957501("+按请求参数生成的json数组+")";
jquery就会通过回调方法动态加载调用这个js tag:jsonp1236827957501(json数组);
这样就达到了跨域数据交换的目的.

jsonp的最基本的原理是:动态添加一个<script>标签,而script标签的src属性是没有跨域的限制的。这样说来,这种跨域方式其实与ajax XmlHttpRequest协议无关了.
这样其实"jQuery AJAX跨域问题"就成了个伪命题了,jquery $.ajax方法名有误导人之嫌.
如果设为dataType: 'jsonp', 这个$.ajax方法就和ajax XmlHttpRequest没什么关系了,取而代之的则是JSONP协议.
JSONP是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问
JSONP即JSON with Padding。由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源。如果要进行跨域请求,
我们可以通过使用html的script标记来进行跨域请求,并在响应中返回要执行的script代码,其中可以直接使用JSON传递javascript对象。
这种跨域的通讯方式称为JSONP。

jsonCallback 函数jsonp1236827957501(....): 是浏览器客户端注册的,获取跨域服务器上的json数据后,回调的函数

Jsonp原理:

首先在客户端注册一个callback (如:'jsoncallback'), 然后把callback的名字(如:jsonp1236827957501)传给服务器。

此时,服务器先生成 json 数据。

然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 'jsoncallback'的值 jsonp1236827957501 .

最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。

客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时javascript文档数据,作为参数,
传入到了客户端预先定义好的 callback 函数(如上例中jquery $.ajax()方法封装的的success: function (json))里.(动态执行回调函数)

可以说jsonp的方式原理上和<script src="http://跨域/...xx.js"></script>是一致的(qq空间就是大量采用这种方式来实现跨域数据交换的) .JSONP是一种脚本注入(Script Injection)行为,所以也有一定的安全隐患.

注意,jquey是不支持post方式跨域的.
为什么呢?
虽然采用post +动态生成iframe是可以达到post跨域的目的(有位js牛人就是这样把jquery1.2.5 打patch的),但这样做是一个比较极端的方式,不建议采用.
也可以说get方式的跨域是合法的,post方式从安全角度上,被认为是不合法的, 万不得已还是不要剑走偏锋..

client端跨域访问的需求看来也引起w3c的注意了,看资料说html5 WebSocket标准支持跨域的数据交换,应该也是一个将来可选的跨域数据交换的解决方案.

Javascript 相关文章推荐
SlideView 图片滑动(扩展/收缩)展示效果
Aug 01 Javascript
jquery getScript动态加载JS方法改进详解
Nov 15 Javascript
关于jquery.validate1.9.0前台验证的使用介绍
Apr 26 Javascript
jquery子元素过滤选择器使用示例
Jun 24 Javascript
jQuery 和 CSS 的文本特效插件集锦
Dec 12 Javascript
js简单实现调整网页字体大小的方法
Jul 23 Javascript
微信小程序 loading 详解及实例代码
Nov 09 Javascript
js绑定事件和解绑事件
Apr 27 Javascript
利用纯js + transition动画实现移动端web轮播图详解
Sep 10 Javascript
Validform验证时可以为空否则按照指定格式验证
Oct 20 Javascript
element-ui 表格实现单元格可编辑的示例
Feb 26 Javascript
浅谈react路由传参的几种方式
Mar 23 Javascript
IE与firefox下Dhtml的一些区别小结
Dec 02 #Javascript
checkbox全选/取消全选以及checkbox遍历jQuery实现代码
Dec 02 #Javascript
两种WEB下的模态对话框 (asp.net或js的分别实现)
Dec 02 #Javascript
JavaScript Object的extend是一个常用的功能
Dec 02 #Javascript
JS类的封装及实现代码
Dec 02 #Javascript
Jquery选择器 $实现原理
Dec 02 #Javascript
js 表格隔行颜色
Dec 02 #Javascript
You might like
浅析十款PHP开发框架的对比
2013/07/05 PHP
PHP检测字符串是否为UTF8编码的常用方法
2014/11/21 PHP
php单例模式的简单实现方法
2016/06/10 PHP
PHP在innodb引擎下快速代建全文搜索功能简明教程【基于xunsearch】
2016/10/14 PHP
php实现的AES加密类定义与用法示例
2018/01/29 PHP
YII框架实现自定义第三方扩展操作示例
2019/04/26 PHP
PHP 自动加载类原理与用法实例分析
2020/04/14 PHP
用JavaScript将从数据库中读取出来的日期型格式化为想要的类型。
2009/08/15 Javascript
jquery学习笔记 用jquery实现无刷新登录
2011/08/08 Javascript
jqGrid增加时--判断开始日期与结束日期(实例解析)
2013/11/08 Javascript
调用innerHTML之后onclick失效问题的解决方法
2014/01/28 Javascript
JavaScript实现页面5秒后自动跳转的方法
2015/04/16 Javascript
Bootstrap导航栏各元素操作方法(表单、按钮、文本)
2015/12/28 Javascript
浅析jquery与checkbox的checked属性的问题
2016/04/27 Javascript
Backbone View 之间通信的三种方式
2016/08/09 Javascript
基于JavaScript实现活动倒计时效果
2017/04/20 Javascript
js求数组中全部数字可拼接出的最大整数示例代码
2017/08/25 Javascript
bootstrap模态框嵌套、tabindex属性、去除阴影的示例代码
2017/10/17 Javascript
浅析为什么a=&quot;abc&quot; 不等于 a=new String(&quot;abc&quot;)
2017/10/25 Javascript
vue将单页面改造成多页面应用的方法
2018/11/25 Javascript
JS实现打字游戏
2019/12/17 Javascript
js实现简易计算器小功能
2020/11/18 Javascript
[01:03:18]DOTA2-DPC中国联赛 正赛 RNG vs Dynasty BO3 第一场 1月29日
2021/03/11 DOTA
Python实现设置windows桌面壁纸代码分享
2015/03/28 Python
Python cookbook(数据结构与算法)从任意长度的可迭代对象中分解元素操作示例
2018/02/13 Python
Python cookbook(数据结构与算法)从字典中提取子集的方法示例
2018/03/22 Python
pandas实现选取特定索引的行
2018/04/20 Python
python网络编程:socketserver的基本使用方法实例分析
2020/04/09 Python
超全Python图像处理讲解(多模块实现)
2020/04/13 Python
Python远程linux执行命令实现
2020/11/11 Python
SIDESTEP荷兰:在线购买鞋子
2019/11/18 全球购物
贪睡宠物用品:Snoozer Pet Products
2020/02/04 全球购物
2014迎国庆标语大全
2014/09/19 职场文书
西安导游词
2015/02/12 职场文书
Springboot/Springcloud项目集成redis进行存取的过程解析
2021/12/04 Redis
一条 SQL 语句执行过程
2022/03/17 MySQL