Ajax
- XMLHttpRequest对象 同/异 步
- 属性
- readyState
- get请求
- post请求
- ajax在IE
- Ajax的缺点
- jQuery中的ajax
- Headers 对象
- Request 对象
- Fetch API 异步
- 基本用法
- 获取二进制数据
- Beacon API
- web Socket
Ajax Asynchronous Javascript +XML
本质:远程脚本
Ajax-无需刷新当前页面即可从服务器获取额外数据的一个方法.
最初是通过JavaScript从服务器获取XML数据的一种手段
- 最初,JavaScript对服务器的请求可以通过中介(如Java小程序、或flash影片),即远程脚本
- 在XHR出现之前Ajax风格的通信必须通过黑科技实现-隐藏的窗格、内嵌窗格。
- XHR由微软提出,又被其他浏览器借鉴,打开一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息,提供了原生的浏览器通信能力。
XHR为发送服务器请求和获取响应提供了合理的接口,该接口可以实现同/异步从服务器获取额外的数据,即用户不用点击页面刷新也可以获得新的数据。 - XHR的API被认为比较难用,所以又推出了fetch API,后者支持promise、service worker。
通过XHR进行请求有一个主要限制是跨域安全策略,默认情况下,XHR只允许访问 与发起请求的页面在同一个域的资源。想要实现跨域XHR,从实现跨域HTTP入手,CORS方法、CSP头部。此外也可以直接不用XHR,采用其他不受跨域限制的方法,jsonp、img图片探测
解决跨域
XMLHttpRequest对象 同/异 步
XMLHttpRequest对象 fetch API
一个异/同步(配置open方法的参数来实现同/异 步)调用对象,设置响应HTTP请求状态变化的函数
let xhr=new XMLHttpRequest();
//收到响应后,xhr的部分属性会被填充赋值
xhr.onreadystatechange=function(){
if(xhr.readyStatus==4){
if(xhr.status>=200&&xhr.status<300||xhr.status==304){
alert(xhr.responseText);
}else{
alert("Request failed :"+xhr.status);
}//不用this取代xhr,防止作用域问题
}
};
xhr.open("get","./url",请求是否异步的布尔值);//请求方法,不请求,只是做准备,只能访问同源URL
//修改添加 应在这时完成
xhr.send(请求体);//无请求体,传入null
一般浏览器自己的默认HTTP消息头都会携带上去,此外
open()与send()函数之间开发者可以使用setRequestHeader()发送自定义的头部
属性
- responseText:作为响应体返回的文本
- responseXML:当响应体是XML时
- status:响应的HTTP状态
- statusText:响应的HTTP状态描述
- readyState:当前处在请求/响应过程的哪一阶段0-4,会触发readystatechange事件,为了保证跨流域兼容,onreadystatechange事件处理程序应该在调用open()之前赋值。
- timeout:毫秒数,不响应触发timeout事件,超时之后访问state会报错,在onreadyState写好catch/try
还有其他进度事件:loadstars、progress、error、
readyState
status是服务器对请求的反馈,而readystate表明客户端的交互状态过程。
ajax.readyState由AJAX对象与服务器交互时所得。无论访问结果如何,运行ajax都一定经历过的状态,即AJAX运行步骤。
(由数字1~4单位数字组成)
0 - (未初始化)还没有调用send()方法
1 - (载入)已调用send()方法,正在发送请求
2 - (载入完成)send()方法执行完成,
3 - (交互)正在解析响应内容
4 - (完成)响应内容解析完成,可以在客户端调用了
监听readyState可以实现解析完成立即调用
get请求
在get请求后添加的查询字符串参数,必须正确编码添加到URL后,然后再传给open()
encodeURLComponent编码,&分割所有名/值对
可以自定义一个addURLParam()来保证编码正确
function addURLParam(url,name,value){
url+=(url.indexOf("?")==-1? "?":"&");
url+=endodeURIComponent(name)+"="+endodeURIComponent(value);
return url;
}
post请求
相比get请求占更多资源,速度慢
向服务器发送应该保存的数据,应该再请求体中携带提交的数据,数据可以是任意格式
默认,服务器而言POST与提交表单不一样。提交表单可以通过添加头部Content-Type来告诉服务器,再通过调用serialize函数序列化表单数据之后作为请求体。除此之外,XHR 2新增了FormData类,保存表单数据,直接可以作为请求体,无需添加特殊头部.
const form = document.getElementById('iii');
xhr.send(serialize(form));
xhr.send(new FormData(form));
// 也可以这样添加数据
FormData.append('key','value')
ajax在IE
在IE浏览器,如果请求的方法是GET,并且请求的URL不变,那么这个请求的结果就会缓存。解决方法就是实时修改请求的URL,只要URL改变,就不会缓存
Ajax的缺点
不支持浏览器的back按钮
又安全问题,Ajax暴露了与服务器交互的细节
对搜索引擎不友好
破坏了程序的异常机制
不容易调试
jQuery中的ajax
$.get(url,[data],[callback])
$.getJSON(url,[data],[callback])
$.post(url,[data],[callback])
$.ajax(option)
$.getScript(url,[data],[callback])
jquery对象.load(url,[data],[callback])
Headers 对象
对象是所有外发请求和入站响应头部的容器,类似Map对象。
get()、set()、deleted()、keys()、values()、entries(),此外
let seed={foo:'bar'};
let h=new Headers(seed);
注意有些情况头部是不允许被更改的,这时候上述函数就会报错
每个外发/入站的Response实例都包含一个Headers实例,可以通过Response.prototype.headers访问
Request 对象
获取资源请求的接口
在fetch中可以传入Request对象
有请求体的对象只能使用一次,因为请求体会被标记为已使用
Fetch API 异步
支持promise、service worker
能够执行XHR对象的所有任务,但更容易使用,是使用js请求资源的工具。
fetch方法给指定URL发送请求,是暴露在全局作用域中,包括主页面执行线程、模块和工作线程。
基本用法
let r=fetch('/资源的url');//返回一个promise
r.then( (response) => {
response.text
})
获取二进制数据
通常后端返回给我们的数据格式是json,获取数据时直接res.json就可以。除此之外,还有其他的格式
过去获取二进制数据,需要通过XMLHttpRequest对象的overrideMimeType方法来重载所获取数据的MIME类型,将所获取数据的字符编码charset修改为用户自定义类型。
HML5的XMLHttpRequest对象新增了responseType(属性值见下) 与response属性
arraybuffer:response 是一个包含二进制数据的 JavaScript ArrayBuffer。
blob:response 是一个包含二进制数据的 Blob 对象 。
document:response 是一个 HTML Document 或 XML XMLDocument,这取决于接收到的数据的 MIME 类型。
json:response 是一个 JavaScript 对象。这个对象是通过将接收到的数据类型视为 JSON 解析得到的。
text:response 是一个以 DOMString 对象表示的文本。
Beacon API
是一个基于JavaScript的Web api,一种非常有用的记录运动方法,可以将数据从页面发送回服务器,尤其是在日志记录环境中,浏览器支持非常广泛,能够无缝地记录数据,而不影响用户体验和网页性能,请求的非阻塞性质意味着性能比XHR和Fetch等替代方案快得多。
信息少量而快速
类似unload这样的情况下成功发送请求,同时不影响下一个页面的载入
任何时候都可以调用,浏览器会把请求添加到一个内部的请求队列,浏览器会主动地发送队列中的请求。
浏览器保证在原始页面已经关闭的情况下也会发送请求。
给navigator添加了一个sendBeacon()方法
navigator.sendBeacon(‘url',数据的有效负载参数);
web Socket
得到了所有主流浏览器的支持
是与服务器的全双工、双向通信渠道,不使用HTTP,而是自定义协议。目的是更快地发送小数据块。这需要支持该协议的专用的服务器,但速度优势明显。
使用JavaScript创建web socket时,一个Http请求会发送到服务器以初始化连接,服务器响应后,使用HTTP的upgrade头部从HTTP协议切换到其他协议。
let socket=new WebSocket("ws://www.example.com/server.php");//不限制同源
socket.send("hihi");
//服务器回答消息,会触发message消息,可通过event.data访问到消息