Ajax/Fetch
Ajax
AJAX 是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
- 优点
- 页面无刷新,用户体验好。
- 减少冗余请求,减轻了服务器负担。
- 基于标准化的并被广泛支持的技术,不需要下载插件。
- 缺点
- 无法回退,对浏览器后退机制造成破坏。
- 对搜索引擎的支持比较弱。
- 无法用URL直接访问。
XmlHttpRequest对象
XmlHttpRequest对象的属性:
- readystate 请求状态。
- responseText 表示响应体的字符创。
- responseXML 表示响应体的XML。
- status 请求返回的HTTP状态码。
- status Text HTTP响应的状态文本。
- onreadystatechange 当处理过程发生变化的时候执行下面的函数。
XMLHttpRequest对象的属性:
- open 打开要发送给服务器的请求。
- send 发送HTTP请求给服务器。
创建ajax的步骤
Ajax的原理简单来说通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用javascript来操作DOM而更新页面。这其中最关键的一步就是从服务器获得请求数据。原生创建ajax可分为以下四步:
1、创建XMLHttpRequest对象
Ajax的核心是XMLHttpRequest对象,它是Ajax实现的关键,发送异步请求、接受响应以及执行回调都是通过它来完成
var xhr = new XMLHttpRequest();
2、准备请求
-
初始化该XMLHttpRequest对象,接受三个参数:
xhr.open(method,url,async);
-
第一个参数表示请求类型的字符串,其值可以是GET或者POST。
-
GET请求:
xhr.open("GET",url,true);
-
POST请求:
xhr.open("POST",url,true);
-
第二个参数是要作为请求发送目标的URL。
-
第三个参数是true或false,表示请求是以异步还是同步的模式发出。
false
:同步模式发出的请求会暂停所有javascript代码的执行,知道服务器获得响应为止,如果浏览器在连接网络时或者在下载文件时出了故障,页面就会一直挂起。
true
:异步模式发出的请求,请求对象收发数据的同时,浏览器可以继续加载页面,执行其他javascript代码。
3、发送请求
xhr.send();
一般情况下,使用Ajax提交的参数多是些简单的字符串,可以直接使用GET方法将要提交的参数写到open方法的url参数中,此时send方法的参数为null或为空。
-
POST请求:
如果需要像 HTML 表单那样 POST 数据,请使用 setRequestHeader()来添加 HTTP 头。然后在send()方法中规定您希望发送的数据:xmlhttp.open("POST",url,true); xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"); xmlhttp.send("fname=Bill&lname=Gates");
4、处理响应
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
console.log(xhr.responseText);
}
}
-
onreadystatechange :当处理过程发生变化的时候执行的函数
-
readyState :ajax处理状态
- 0:请求未初始化(还没有调用 open())。
- 1:请求已经建立,但是还没有发送(还没有调用 send())。
- 2:请求已发送,正在处理中(通常现在可以从响应中获取内容头)。
- 3:请求在处理中;通常响应中已有部分数据可用了,但是服务器还没有完成响应的生成。
- 4:响应已完成;可以获取并使用服务器的响应了。
-
responseText:获得字符串形式的响应数据
-
返回值一般为json字符串,可以用JSON.parse(xhr.responseText)转化为JSON对象
5、完整例子
function ajax(url, success, fail){
// 1. 创建连接
var xhr = null;
xhr = new XMLHttpRequest()
// 2. 连接服务器
xhr.open('get', url, true)
// 3. 发送请求
xhr.send(null);
// 4. 接受请求
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if(xhr.status == 200){
success(xhr.responseText);
} else { // fail
fail && fail(xhr.status);
}
}
}
}
jQuery中的Ajax
jQuery中的ajax封装案例
//ajax请求后台数据
var btn = document.getElementsByTagName("input")[0];
btn.onclick = function(){
ajax({//json格式
type:"post",
url:"post.php",
data:"username=poetries&pwd=123456",
asyn:true,
success:function(data){
document.write(data);
}
});
}
//封装ajax
function ajax(aJson){
var ajx = null;
var type = aJson.type || "get";
var asyn = aJson.asyn || true;
var url = aJson.url; // url 接收 传输位置
var success = aJson.success;// success 接收 传输完成后的回调函数
var data = aJson.data || '';// data 接收需要附带传输的数据
if(window.XMLHttpRequest){//兼容处理
ajx = new XMLHttpRequest();//一般浏览器
}else
{
ajx = new ActiveXObject("Microsoft.XMLHTTP");//IE6+
}
if (type == "get" && data)
{
url +="/?"+data+"&"+Math.random();
}
//初始化ajax请求
ajx.open( type , url , asyn );
//规定传输数据的格式
ajx.setRequestHeader('content-type','application/x-www-form-urlencoded');
//发送ajax请求(包括post数据的传输)
type == "get" ?ajx.send():ajx.send(aJson.data);
//处理请求
ajx.onreadystatechange = function(aJson){
if(ajx.readState == 4){
if (ajx.status == 200 && ajx.status<300)//200是HTTP 请求成功的状态码
{
//请求成功处理数据
success && success(ajx.responseText);
}else{
alert("请求出错"+ajx.status);
}
}
}
Fetch
fetch号称是AJAX的替代品,它是W3C的正式标准。Fetch API提供了一个fetch()方法,你可以用它来发起对远程资源的请求。 该方法返回的是一个Promise对象。
下面我们写一些代码来具体的介绍它的用法:
function fetchDemo() {
fetch(URL).then(function(response) {
return response.json();
}).then(function(json) {
console.log(json);
});
}
fetchDemo();
上面的代码看起来很简单:首先是构造请求的URL,然后将URL传递给全局的fetch()方法,它会立刻返回一个Promise, 当Promise被通过,它会返回一个Response对象,通过该对象的json()方法可以将结果作为JSON对象返回。 response.json()同样会返回一个Promise对象,因此在我们的例子中可以继续链接一个then()方法。
我们再来看一个传统的XMLHttpRequest的方式:
function xhrDemo() {
var xhr = new XMLHttpRequest();
xhr.onload = function() {
console.log(JSON.parse(xhr.responseText));
};
xhr.open('GET', URL);
xhr.send();
}
可以发现,主要的不同点在于:传统上我们会使用事件处理器,而不是Promise对象。 并且请求的发起完全依赖于xhr对象所提供的方法。
为什么需要替代XMLHttpRequest
对于传统的XMLHttpRequest而言,你必须使用它的一个实例来执行请求和检索返回的响应。 但是通过Fetch API,我们还能够明确的配置请求对象。
你可以通过Request构造器函数创建一个新的请求对象,这也是建议标准的一部分。 第一个参数是请求的URL,第二个参数是一个选项对象,用于配置请求。请求对象一旦创建了, 你便可以将所创建的对象传递给fetch()方法,用于替代默认的URL字符串。示例代码如下:
var req = new Request(URL, {method: 'GET', cache: 'reload'});
fetch(req).then(function(response) {
return response.json();
}).then(function(json) {
console.log(json);
});
上面的代码中我们指明了请求使用的方法为GET,并且指定不缓存响应的结果。
有关Request对象的另一件更厉害的事在于,你还可以基于原有的对象创建一个新的对象。 新的请求和旧的并没有什么不同,但你可以通过稍微调整配置对象,将其用于不同的场景。 例如,你可以基于原有的GET请求创建一个POST请求,它们具有相同的请求源。代码如下:
// 基于req对象创建新的postReq对象
var postReq = new Request(req, {method: 'POST'});
总结一下,Fetch 优点主要有:
-
语法简洁,更加语义化。
-
基于标准 Promise 实现,支持 async/await。
但Fetch中也存在一些缺点:
- fetch只对网络请求报错,对400,500都当做成功的请求,需要封装去处理
- fetch默认不会带cookie,需要添加配置项
- 原生支持率并不高。