ajax
- 创建ajax
function createXHR(){
if(typeOf XMLHttpRequest != 'undefined'){
return new XMLHttpRequest();
}else if(typeOf ActiveXObject != 'undefined'){
if(typeOf arguments.callee.activeXString != 'string'){
let version = ['MSXML2.XMLHttp.6.0','MSXML2.XMLHttp.3.0','MSXML2.XMLHttp']; for(i=0;i<version.length;i++){
try {
new ActiveXObject(version[i]);
arguments.callee.activeXString = version[i];
break;
} catch(ex) {
//跳过
};
};
};
}else{
throw new Error('No XHR object available.');
};
};
let xhr = new createXHR();2.调用open();
- 三个参数:要发送的请求的类型('get','post'等);请求的URL;是否异步发送请求的布尔值;
- 调用:xhr.open('get','example.php',true);
- 说明两点:一是URL相对于执行代码的当前页面(也可以是绝对路径);二是调用open()方法并不会真正发送请求,而是启动一个请求以备发送。
- 注意:同源策略(同域名,同协议,同端口);
3.调用send();
- 一个参数:作为请求主体发送的数据,如果不需要必须传null.
- 调用send()后,请求就会被分派到服务器。
4.监听readystatechange事件,获取xhr的readyState和status属性值
- 同步请求判断xhr的status属性就可以,异步请求既需要获取xhr的readyState属性又要获取xhr的status属性
- readyState
1)该属性表示请求/响应的当前活动阶段
2)属性值
- 0:未初始化。尚未调用open()方法;
- 1:启动。已经调用open()方法,但尚未调用send()方法;
- 2:发送。已经调用send()方法,但尚未收到响应;
- 3:接收。已经收到部分响应数据;
- 4:完成。已经收到全部响应数据,而且已经可以在客户端使用了。
- status
1)该属性表示:响应的HTTP状态
2)成功返回(200<=status<300和304)
- xhr响应返回填充的属性
1)responseText:作为响应主体被返回的文本
2)responseXML:如果响应的内容类型是'text/xml'或'application/xml',这个属性中将保存着包含着响应数据的XML DOM文档。
3)statusText:HTTP状态的说明
let xhr = new createXHR();
xhr.onreadystatechange = function(){
if(xhr.readyState==4){
if((xhr.status>=200 && xhr.status<300) || xhr.status == 304){
alert(xhr.responseText);
};
};
};
xhr.open('get','example.text',true);
xhr.send(null)5.abort()方法
- 调用这个方法后,XHR对象会停止触发事件,而且也不允许访问任何与响应有关的对象属性
6.setRequestHeader()
- 接收两个参数:头部字段的名称和头部字段的值。必须在open()方法之后和send()方法之前调用setRequestHeader方法
备注:
1.get请求
- 适用:用于向服务器查询某些信息。
- 可以将查询字符串参数追加到URL的末尾,但是要正确编码。添加参数函数:
function addURLParam(url,name,value){
url += (url.indexOf('?')==-1?'?':'&');
url += encodeURIComponent(name) + '=' + encodeURIComponent(value);
return url;
};2.post请求
- 适用:通常用于向服务器发送应该被保存的数据。
3.get和post的优缺点:
- 资源:psot消耗的资源更多
- 速度:传送的数据相同,get的速度最多是post的两倍
解决跨域的方法:(参考https://www.cnblogs.com/sdcs/p/8484905.html)
- 通过jsonP跨域
- 原理:通过script标签来引入一个js文件,这个js文件载入成功后会执行我们在url参数中指定的函数,并且把我们需要的json数据作为参数传入。但是jsonp这种方式是需要服务端对应页面进行相应配合的。
2.通过修改document.domain来跨子域
- 适用:浏览器中不同域的框架之间是不能进行js交互的
- 例如:www.example.com/a.html 和 example.com/b.html这两个页面的document.domain都设成相同的域名就可以了。但要注意的是,document.domain的设置是有限制的,我们只能把document.domain设置成自身或更高一级的父域,且主域必须相同。例如:a.b.example.com 中某个文档的document.domain 可以设成a.b.example.com、b.example.com 、example.com中的任意一个,但是不可以设成 c.a.b.example.com,因为这是当前域的子域,也不可以设成baidu.com,因为主域已经不相同了。
- 注意:修改document.domain的方法只适用于不同子域的框架间的交互。如果你想通过ajax的方法去与不同子域的页面交互,除了使用jsonp的方法外,还可以用一个隐藏的iframe来做一个代理。原理就是让这个iframe载入一个与你想要通过ajax获取数据的目标页面处在相同的域的页面,所以这个iframe中的页面是可以正常使用ajax去获取你要的数据的,然后就是通过我们刚刚讲得修改document.domain的方法,让我们能通过js完全控制这个iframe,这样我们就可以让iframe去发送ajax请求,然后收到的数据我们也可以获得了。
3.使用window.name来进行跨域
- window对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的,并不会因新页面的载入而进行重置。
- 注意:window.name的值只能是字符串的形式,这个字符串的大小最大能允许2M左右甚至更大的一个容量,具体取决于不同的浏览器,但一般是够用了。
- 原理:在a.html页面中使用一个隐藏的iframe来充当一个中间人角色,由iframe去获取data.html的数据,然后a.html再去得到iframe获取到的数据。
4.通过HTML5中新引入的window.postMessage()方法来跨域传送数据。
- 原理:window.postMessage(message,targetOrigin) 方法是html5新引进的特性,可以使用它来向其它的window对象发送消息,无论这个window对象是属于同源或不同源,目前IE8+、FireFox、Chrome、Opera等浏览器都已经支持window.postMessage方法。
- 参数:第一个参数message为要发送的消息,类型只能为字符串;第二个参数targetOrigin用来限定接收消息的那个window对象所在的域,如果不想限定域,可以使用通配符 * 。
- 接收:要接收消息的window对象,可是通过监听自身的message事件来获取传过来的消息,消息内容储存在该事件对象的data属性中。
- 适用:一个页面有几个框架的那种情况,因为每一个框架都有一个window对象。在讨论第二种方法的时候,我们说过,不同域的框架间是可以获取到对方的window对象的,而且也可以使用window.postMessage这个方法