Ajax
是异步的Javascript和XML(Asynchronous Javascript And XML)。
其实就是使用 XMLHttpRequest
(由XMLHttpRequest()函数实例化的一个对象,可以与服务器交互) 对象与服务器进行通信,它可以使用JSON,XML,HTML,text等格式发送和接受数据。其最大的特点就是它的‘异步’,它可以在不刷新页面的情况下与服务器进行通信,数据交换,局部更新页面。
利用Ajax发送http请求:
if (window.XMLHttpRequest) { // Mozilla, Safari, IE7+ ...
httpRequest = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE 6 and older
httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
//实例XMLHttp
首先看一个例子:
<button id="ajaxButton" type="button">Make a request</button>
<script>
(function() {
var httpRequest;
document.getElementById("ajaxButton").addEventListener('click', makeRequest);
function makeRequest() {
httpRequest = new XMLHttpRequest();
if (!httpRequest) {
alert('Giving up :( Cannot create an XMLHTTP instance');
return false;
}
httpRequest.onreadystatechange = alertContents;
httpRequest.open('GET', 'test.html');
httpRequest.send();
}
function alertContents() {
if (httpRequest.readyState === XMLHttpRequest.DONE) {
if (httpRequest.status === 200) {
alert(httpRequest.responseText);
} else {
alert('There was a problem with the request.');
}
}
}
})();
</script>
- 用户点击button Mask a request;
- 事件绑定调用makeRequest();
- 请求通过后alertContents()赋值给httpRequest.onreadystatechange
- alertContents()来检测response是否正确,正确响应后alert() test.html内容
发送一个请求后,你会收到响应。在这一阶段,你要告诉XMLHttp请求对象是由哪一个JavaScript函数处理响应,在设置了对象的 onreadystatechange 属性后给他命名,当请求状态改变时调用函数。
httpRequest.onreadystatechange = nameOfTheFunction;
//即 httpRequest.onreadystatechange = alertContents;
此函数名没有参数,因为你把一个引用赋值给了函数,而不是调用,也可以直接赋值
httpRequest.onreadystatechange = function(){
...
};
接着我们会发送一个实际的请求,通过调用http请求对象的open()和send()方法:
httpRequest.open('GET', 'http://www.example.org', true);
httpRequest.send();
//即 httpRequest.open('GET', 'test.html');
httpRequest.send();
- open() 的第一个参数是HTTP请求方法 - 有GET,POST,HEAD以及服务器支持的其他方法。 保证这些方法一定要是大写字母,否则其他一些浏览器(比如FireFox)可能无法处理这个请求。
- 第二个参数是你要发送的URL。由于安全原因,默认不能调用第三方URL域名。 确保你在页面中使用的是正确的域名,否则在调用 open() 方法是会有 “权限被拒绝” 错误提示。记得别忘了www。
- 第三个参数是可选的,用于设置请求是否是异步的。如果设为 true (默认设置),JavaScript执行会持续,并且在服务器还没有响应的情况下与页面进行交互。
接下来send()方法:
其参数为你发送给服务器的内容,如果是post请求,需要发送服务器可以解析的数据格式,如:
"name=value&anothername="+encodeURIComponent(myVar)+"&so=on"
或者其他form-data,JSON,XMl,text等等。
如果使用 POST 数据,那就需要设置请求的MIME类型。比如,在调用 send() 方法获取表单数据前要有下面这个:
httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
发送请求时,利用onreadystatechange来处理响应:
httpRequest.onreadystatechange = nameOfTheFunction;
首先处理函数要去检查请求的状态,如果XMLHttpRequest.DONE
(对应值为4),意味着服务器服务器响应收到并且无误,after继续执行
if (httpRequest.readyState === XMLHttpRequest.DONE) {
// go on
} else {
// Not ready yet.
}
readyState对应状态:
- 0 未初始化 or 请求还未初始化;
- 1 正在加载 or 已建立服务器链接;
- 2 加载成功 or 请求已接受;
- 3 交互 or 正在处理请求;
- 4 完成 or 请求已完成并且响应已返回;
接着,通过检查响应状态来区分Ajax调用是否成功;
if (httpRequest.status === 200) {
// Perfect!
} else {
// 404 or 500等等
}
成功后就可以得到服务器返回的数据,可以利用这些数据去页面渲染等,可以通过两个方法访问这些数据:
httpRequest.responseText
– 服务器以文本字符的形式返回httpRequest.responseXML
– 以 XMLDocument 对象方式返回,之后就可以使用JavaScript来处理
上面这步是Ajax发起异步请求时有效(既 open() 的第三个参数未特别指定或设为 true),如果是同步则不需要使用函数(不推荐,用户体验差)
注意
- 如果你向一个代码片段发送请求,将返回XML,而不是静态XML文件,在IE浏览器上则必须要设置响应头才能正常工作。如果不设置响应头为
Content-Type:application/xml
,IE浏览器会在你访问XML元素时抛出 “Object Expected” 错误。 - 如果不设置响应头
Cache-Control: no-cache
浏览器将会把响应缓存下来而且再也无法重新提交请求。你也可以添加一个总是不同的 GET 参数,比如时间戳或者随机数。 - 如果变量 httpRequest 在全局范围内使用,它会在 makeRequest() 函数中被相互覆盖,从而导致资源竞争。为了避免这个情况,可以在包含 AJAX 函数的闭包中声明 httpRequest 变量。
另外:
在错误通信的事件中,为防止程序崩溃等现象,可以使用try…catch将请求的返回函数包裹
function alertContents() {
try {
if (httpRequest.readyState === XMLHttpRequest.DONE) {
if (httpRequest.status === 200) {
alert(httpRequest.responseText);
} else {
alert('There was a problem with the request.');
}
}
}
catch( e ) {
alert('Caught Exception: ' + e.description);
}
}
处理XML响应
上面例子在收到http的请求响应后,我们会请求对象的responseText 属性,包含 test.html 文件的内容。下面看一下responseXML
属性:
首先,创建XML文档。
//test.xml
<?xml version="1.0" ?>
<root>
I'm a test.
</root>
然后在脚本里面更改请求行为:
...
onclick="makeRequest('test.xml')">
...
然后在alertContents()里,将数据读取方式改为responseXML
:
var xmldoc = httpRequest.responseXML;
var root_node = xmldoc.getElementsByTagName('root').item(0);
alert(root_node.firstChild.data);
用 responseXML
提供的 XMLDocument
对象,并使用 DOM 方法访问 XML 文档中包含的一些数据。
数据处理
大多是前端页面的数据展示和一些交互,和项目架构有部分关系,如果是使用原生渲染便是一些原生dom操作,增删改插入,事件绑定,事件监听等等,像react可能涉及state,props,jsx等,vue的data,computed,mothods以及watch等等,其实也都是封装的原生方法,所谓换汤不换药。
-------END.