解决ajax跨域请求 (总结)
ajax跨域请求,目前已用几种方法实现:
1)用原生js的xhr对象实现。
var url="http://freegeoip.net/json/";
//创建xhr对象
function createCORSXhr(url,method){
var xhr=new XMLHttpRequest();
if("withCredentials" in xhr){
xhr.open(method,url,true);
}else if(typeof XDomainRequest !=="undefined"){
xhr=new XDomainRequest();
xhr.open(method,url);
}else
xhr=null;
return xhr;
}
//创建ajax请求,支持跨域
function sendAjaxRequest(){
var xhr=createCORSXhr(url,"get");
xhr.onload=function(){
if(xhr.readyState==4){
if(xhr.status>=200 && xhr.status<300 || xhr.status==304){
alert(xhr.responseText);
}else{
alert(" ajax error...")
}
}
};
xhr.onerror=function(){
alert("error code:"+xhr.status)
}
xhr.send(null);
};
sendAjaxRequest()
这种方式需要获取相应对象的支持,对于IE,则是XDomainRequest,此种方式cookie不会参与传递。该方式应用了CORS(跨域资源共享)技术,说到底,就是在请求头和响应头中做手脚。在请求头中,加上Origin:协议+域名+端口,当然也可以Origin:null。在响应头中,服务端返回Access-control-Allow-Origin:*.
2),通过jsonp数据来实现,说白了,jsonp就是js可执行文件,由于<script>和<link>,<img>加载的文件不受同源限制,所以可以通过设置src和href来加载相应的跨域json或者xml数据,但是这种方式需要服务端相配合(服务端需要取出请求字符串中的回调函数名,并且返回给客户端)。jsonp的格式为:回调函数名(jsonData)。
jQuery中的$.getJSON()默认实现了这种方式,只需要在url?callback=?即可,当然也可以手动指定回调函数名。
该种方式一定需要服务端的配合。
测试网站:http://freegeoip.net/json/
3),第三个就是websocket了,当然需要这样的服务器支持。标准的http服务器是不支持webSocket的。Tomcat7.XX支持websocket。
4),
使用window.name来进行跨域
window对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的,并不会因新页面的载入而进行重置。
比如:有一个页面a.html,它里面有这样的代码:
再看看b.html页面的代码:
a.html页面载入后3秒,跳转到了b.html页面,结果为:
我们看到在b.html页面上成功获取到了它的上一个页面a.html给window.name设置的值。如果在之后所有载入的页面都没对window.name进行修改的话,那么所有这些页面获取到的window.name的值都是a.html页面设置的那个值。当然,如果有需要,其中的任何一个页面都可以对window.name的值进行修改。注意,window.name的值只能是字符串的形式,这个字符串的大小最大能允许2M左右甚至更大的一个容量,具体取决于不同的浏览器,但一般是够用了。
上面的例子中,我们用到的页面a.html和b.html是处于同一个域的,但是即使a.html与b.html处于不同的域中,上述结论同样是适用的,这也正是利用window.name进行跨域的原理。
下面就来看一看具体是怎么样通过window.name来跨域获取数据的。还是举例说明。
比如有一个www.example.com/a.html页面,需要通过a.html页面里的js来获取另一个位于不同域上的页面www.cnblogs.com/data.html里的数据。
data.html页面里的代码很简单,就是给当前的window.name设置一个a.html页面想要得到的数据值。data.html里的代码:
那么在a.html页面中,我们怎么把data.html页面载入进来呢?显然我们不能直接在a.html页面中通过改变window.location来载入data.html页面,因为我们想要即使a.html页面不跳转也能得到data.html里的数据。答案就是在a.html页面中使用一个隐藏的iframe来充当一个中间人角色,由iframe去获取data.html的数据,然后a.html再去得到iframe获取到的数据。
充当中间人的iframe想要获取到data.html的通过window.name设置的数据,只需要把这个iframe的src设为www.cnblogs.com/data.html就行了。然后a.html想要得到iframe所获取到的数据,也就是想要得到iframe的window.name的值,还必须把这个iframe的src设成跟a.html页面同一个域才行,不然根据前面讲的同源策略,a.html是不能访问到iframe里的window.name属性的。这就是整个跨域过程。
看下a.html页面的代码:
上面的代码只是最简单的原理演示代码,你可以对使用js封装上面的过程,比如动态的创建iframe,动态的注册各种事件等等,当然为了安全,获取完数据后,还可以销毁作为代理的iframe。网上也有很多类似的现成代码,有兴趣的可以去找一下。
- 洛谷P2860 [USACO06JAN]冗余路径Redundant Paths(tarjan求边双联通分量)
- 关于类的对象创建与初始化
- 1191: [HNOI2006]超级英雄Hero
- 2005: [Noi2010]能量采集
- 1067: [SCOI2007]降雨量
- 2761: [JLOI2011]不重复数字(哈希表)
- 1297: [SCOI2009]迷路
- Javascript DOM操作实例
- 2431: [HAOI2009]逆序对数列
- JavaScript实例---表格隔行变色以及移入鼠标高亮
- 1022: [SHOI2008]小约翰的游戏John
- Javascript数组
- 1588: [HNOI2002]营业额统计
- [git]撤销的相关命令:reset、revert、checkout
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android 中通过ViewDragHelper实现ListView的Item的侧拉划出效果
- 浅谈Android中使用异步线程更新UI视图的几种方法
- Android gradle打包并自动上传的方法
- Android 后台发送邮件到指定邮箱
- Android中socketpair双向通信详解
- Android滚动条广告实现代码示例
- Android使用Recyclerview实现图片水平自动循环滚动效果
- Android selector的实例详解
- Android底部弹窗的实现示例代码
- Android编程实现自定义渐变颜色效果详解
- ES11屡试不爽的新特性,你用上了几个?
- Android设计模式之策略模式详解
- Android实现类似iOS风格的对话框实例代码
- Android 给图片加上水印的示例代码(支持logo+文字)
- Android studio 下JNI编程实例并生成so库的实现代码