AJAX异步请求
AJAX即Asynchronous Javascript And XML,指异步JavaScript和XML的HTTP网络请求。AJAX异步HTTP请求在浏览器前端开发中应用十分广泛,我们知道传统网页是同步式的,一次HTTP请求响应一个HTML页面,而AJAX则是异步发起HTTP请求,根据返回结果的XML数据进行DOM或其他操作,整个HTML页面不用刷新即可动态更新展示数据,因此能够实现极其复杂的交互体验。
注:随着技术发展,现在我们更倾向于使用JSON作为数据交换格式,而非之前曾风靡一时的XML格式。
XMLHttpRequest(XHR)
XMLHttpRequest对象是AJAX技术的核心,它用于发起异步请求。
方法
open(method, url, async):参数为请求类型,资源URL,同步还是异步(实际上只能取true)send(str):异步发送消息,参数为发送的请求体字符串,参数仅用于POST,GET时send无参数即可setRequestHeader(header, value):设置请求头信息,例如:提交表单需要设置请求头为xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
属性
responseText:服务器的响应字符串responseXML:服务器响应的XML,和responseText的区别是responseXML返回的是XMLDocument对象,直接使用DOM解析即可。onreadystatechange:每次readystate改变都回调对应的函数readystate参数:- 0:请求未初始化
- 1:服务器已建立连接
- 2:请求已接收
- 3:请求处理中
- 4:请求已完成
status:状态码,如200表示请求成功,正常完成
AJAX使用实例
下面代码展示了XHR如何发起GET请求。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo AJAX</title>
</head>
<body>
<button onclick="ajax()">click</button>
<div id="div"></div>
<script>
function ajax()
{
var xhr = new XMLHttpRequest();
xhr.open("GET", "test.txt");
xhr.send();
xhr.onreadystatechange = function()
{
if(xhr.readyState == 4 && xhr.status == 200)
{
document.querySelector("#div").innerHTML = xhr.responseText;
}
};
}
</script>
</body>
</html>
上面代码中,当我们点击按钮,XHR会异步请求test.txt的内容,将其以文本形式显示到<div>中。
FetchAPI
在最新的浏览器中,引入了一个独立于XHR的全新AJAX接口FetchAPI。下面是一段例子代码,实现了上方代码完全同样的功能。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo AJAX</title>
</head>
<body>
<button onclick="ajax()">click</button>
<div id="div"></div>
<script>
function ajax()
{
fetch('test.txt').then(
rsp => rsp.text().then(
txt => document.querySelector("#div").innerHTML = txt
)
);
}
</script>
</body>
</html>
FetchAPI相比XHR使用更加方便,其API设计上更为先进。然而FetchAPI的兼容性在目前来说仍有较大问题,IE浏览器全部版本(包括最新的IE11)都不支持FetchAPI,具体使用时需要注意这一点。
AJAX相关库
- JQuery:JQuery库可以说是相当强大的一个库,包含了前端开发必备的各种功能,其对XHR有一套良好的封装
- Axios:这个库封装了冗长的XHR,而写法类似FetchAPI,Axios非常轻巧好用而且还保证了兼容性,在现代前端项目开发中,如果完全不使用JQuery,实现AJAX时Axios是一个不错的选择
- Polyfill:Polyfill是一个能让旧浏览器用兼容性方式实现新功能(如FetchAPI)的库,功能非常强大也非常实用
常见问题
URL参数路径
无论XHR还是Fetch,这个URL参数的写法和页面中的资源路径是完全一致的,例如当前URL是http://a.com/b/:如果请求http://xxx.com/xxx,这是绝对路径,浏览器直接请求该路径;如果是/xxx.txt,/代表网站根目录,因此请求http://a.com/xxx.txt;如果是xxx.txt,则请求同级目录下的xxx.txt,即http://a.com/b/xxx.txt。
AJAX跨域问题
浏览器中AJAX是不允许跨域请求的,这是出于安全考虑而做出的限制。JavaScript能够读取Cookie、Web Storage、indexedDB等应用数据,如果能够跨域请求,当页面被xss攻击时,这些信息就会泄露。
然而,实际开发中有时候确实有AJAX跨域访问的需求,这时可以考虑在服务器端加上CORS响应头、JSONP等手段解决。
AJAX上传文件
HTML5后,AJAX可以通过提交手动拼装的FormData对象实现异步的小文件上传,对于旧浏览器,则只能考虑构造一个隐藏的<iframe>来解决这个问题(写法非常不优雅)。JQuery有一个ajaxFileUpload插件,可以方便的解决文件上传功能的跨浏览器兼容问题。
对于较大文件,建议使用HTML5的ArrayBuffer等新功能来实现分块上传。