AJAX即Asynchronous Javascript And XML,指异步JavaScript和XML的HTTP网络请求。
AJAX异步HTTP请求应用十分广泛,我们知道传统网页是同步式的,一次HTTP请求响应一个HTML页面,而AJAX则是异步发起HTTP请求,根据返回结果的XML数据进行DOM或其他操作,整个HTML页面不用刷新即可动态更新展示数据,因此能够实现极其复杂的交互体验。
注:随着技术发展,现在我们更倾向于使用JSON作为数据交换格式,而非之前曾风靡一时的XML格式。
XMLHttpRequest对象用于发起异步请求。
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
参数:status
:状态码,如200表示请求成功,正常完成ajax发起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>
上述代码中,点击按钮,请求了test.txt的内容,将其以文本形式显示到div中。
在最新的浏览器中,引入了一个独立于XHR的全新AJAX接口fetch()
。下面是一段例子代码,实现了上方代码完全同样的功能:
<!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浏览器,具体使用时需要注意这一点。
无论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是不允许跨域请求的,这是出于安全的考虑。JavaScript能够读取Cookie
,Web Storage
, indexedDB
等应用数据,如果能够跨域请求,当页面被xss攻击时,这些信息就会泄露。
但有时候确实有ajax跨域的需求,这时可以考虑服务器端加上CORS响应头、jsonp等手段解决。
HTML5后,ajax可以通过提交手动拼装的FormData
对象实现异步的小文件上传,对于旧浏览器,则只能考虑构造一个隐藏的iframe来解决这个问题(写法非常不优雅)。JQuery有一个ajaxFileUpload
插件,可以方便的解决文件上传的跨浏览器兼容问题。
对于较大文件,建议使用HTML5的ArrayBuffer等新功能来实现分块上传。