Javascript 中 ajax 和 axiosfetch 的区别
Posted 福州-司马懿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Javascript 中 ajax 和 axiosfetch 的区别相关的知识,希望对你有一定的参考价值。
首先介绍一下 BootCDN
BootCDN 是 Bootstrap 中文网支持并维护的前端开源项目免费 CDN 服务,致力于为 Bootstrap、jQuery、Angular、Vuejs 一样优秀的前端开源项目提供稳定、快速的免费 CDN 加速服务。BootCDN 所收录的开源项目主要同步于 cdnjs 仓库。
后续要用到的 JS 插件的CDN地址均可以从该网站找到。
ajax
AJAX = Asynchronous javascript and XML(异步的 JavaScript 和 XML)
AJAX 的作用是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
XMLHttpRequest 的 readyState 属性
当请求被发送到服务器时,我们需要执行一些基于响应的任务。因此 XMLHttpRequest 提供了 onreadystatechange 函数,每当 readyState 属性发生改变时,就会调用该函数。
onreadystatechange 函数没有参数,参数都存在它的调用者 XMLHttpRequest 里面了。
readyState 一共有 5 种状态
- 0 请求未初始化
- 1 服务器连接已建立
- 2 请求已接收
- 3 请求处理中
- 4 请求已完成,且响应已就绪
const xhr = new XMLHttpRequest();
xhr.onreadystatechange=()=>
console.log( "readyState: " + xhr.readyState );
console.log( "status: " + xhr.status);
正常 的状态变化流程 2 -> 3 -> 4
访问不存在的页面 的状态变化流程 2 -> 3 -> 4
因此,理论上只需要判断 readyState 为 4 的时候,status 的状态值即可。
XMLHttpRequest 的 status 属性
XMLHttpRequest 对象的 status 和 statusText 属性保存有服务器返回的 http 状态码。
- status 属性保存的状态码是以数字表示的
- statusText 属性保存的状态码是以字符串表示的
XMLHttpRequest 对象 status 和statusText 属性对照表
status | statusText | 说明 |
---|---|---|
0** | - | 未被始化 |
1** | - | 请求收到,继续处理 |
100 | Continue | 客户必须继续发出请求 |
101 | Switching protocols | 客户要求服务器根据请求转换HTTP协议版本 |
2** | - | 操作成功收到,分析、接受 |
200 | OK | 交易成功 |
201 | Created | 提示知道新文件的URL |
202 | Accepted | 接受和处理、但处理未完成 |
203 | Non-Authoritative Information | 返回信息不确定或不完整 |
204 | No Content | 请求收到,但返回信息为空 |
205 | Reset Content | 服务器完成了请求,用户代理必须复位当前已经浏览过的文件 |
206 | Partial Content | 服务器已经完成了部分用户的GET请求 |
3** | - | 完成此请求必须进一步处理 |
300 | Multiple Choices | 请求的资源可在多处得到 |
301 | Moved Permanently | 删除请求数据 |
302 | Found | 在其他地址发现了请求数据 |
303 | See Other | 建议客户访问其他URL或访问方式 |
304 | Not Modified | 客户端已经执行了GET,但文件未变化 |
305 | Use Proxy | 请求的资源必须从服务器指定的地址得到 |
306 | 前一版本HTTP中使用的代码,现行版本中不再使用 | |
307 | Temporary Redirect | 申明请求的资源临时性删除 |
4** | - | 请求包含一个错误语法或不能完成 |
400 | Bad Request | 错误请求,如语法错误 |
401 | Unauthorized | 请求授权失败 |
402 | Payment Required | 保留有效ChargeTo头响应 |
403 | Forbidden | 请求不允许(由于服务器上文件或目录的权限设置导致资源不可用) |
404 | Not Found | 没有发现文件、查询或URl(没有找到指定的资源) |
405 | Method Not Allowed | 用户在Request-Line字段定义的方法不允许 |
406 | Not Acceptable | 根据用户发送的Accept拖,请求资源不可访问 |
407 | Proxy Authentication Required | 类似401,用户必须首先在代理服务器上得到授权 |
408 | Request Timeout | 客户端没有在用户指定的饿时间内完成请求 |
409 | Conflict | 对当前资源状态,请求不能完成 |
410 | Gone | 服务器上不再有此资源且无进一步的参考地址 |
411 | Length Required | 服务器拒绝用户定义的Content-Length属性请求 |
412 | Precondition Failed | 一个或多个请求头字段在当前请求中错误 |
413 | Request Entity Too Large | 请求的资源大于服务器允许的大小 |
414 | Request-URI Too Long | 请求的资源URL长于服务器允许的长度 |
415 | Unsupported Media Type | 请求资源不支持请求项目格式 |
416 | Requested Range Not Suitable | 请求中包含Range请求头字段,在当前请求资源范围内没有range指示值,请求也不包含If-Range请求头字段 |
417 | Expectation Failed | 服务器不满足请求Expect头字段指定的期望值,如果是代理服务器,可能是下一级服务器不能满足请求 |
5** | - | 服务器执行一个完全有效请求失败 |
500 | Internal Server Error | 服务器产生内部错误 |
501 | Not Implemented | 服务器不支持请求的函数 |
502 | Bad Gateway | 服务器暂时不可用,有时是为了防止发生系统过载 |
503 | Service Unavailable | 服务器过载或暂停维修 |
504 | Gateway Timeout | 关口过载,服务器使用另一个关口或服务来响应用户,等待时间设定值较长 |
505 | HTTP Version Not Supported | 服务器不支持或拒绝支请求头中指定的HTTP版本 |
12029 | an unknown error occurred while processing the request on the server. the status code returned from the server was : 12029 | 原因:网络不通. 刷新一下就知道了 |
原生JS
class Ajax
get(url, successFn, failFn)
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange=()=>
this.deal(xhr, successFn, failFn);
xhr.send();
post(url, data, successFn, failFn)
const xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
// 添加http头,发送信息至服务器时内容编码类型
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function()
this.deal(xhr, successFn, failFn);
;
xhr.send(data);
deal(xhr, successFn, failFn)
//console.log( "readyState: " + xhr.readyState );
//console.log( "status: " + xhr.status);
if(xhr.readyState == 4)
if(xhr.status == 200 || xhr.status == 304)
successFn.call(this, xhr.responseText);
else
failFn.call(this, xhr.status, xhr.statusText, xhr);
const ajax = new Ajax();
ajax.get('http://jsonplaceholder.typicode.com/users/',
(responseText)=>
console.log("success");
console.log(responseText);
//这里返回的是PlainText,要转化为JSON/JSONArray,可以用JSON.parse(str)方法
const responseObj = JSON.parse(responseText);
console.log(responseObj);
, (status, statusText, xhr)=>
console.log("fail");
console.log(status);
console.log(xhr);
);
可以看到原生返回的只是字符串而已。之所以JQuery之流的插件返回的是JSON对象,是因为在内部调用了JSON.parse方法替我们转化了。
另外,我这里假设服务器返回的数据,json转化一定会成功。但如果服务器下发的不是json数据,那么就会报异常,并且中断后续的执行。
如果这里允许采用降级方案,那么就需要用到 try… catch 函数进行异常捕获了。
const ajax = new Ajax();
ajax.get('http://jsonplaceholder.typicode.com/users/',
(responseText)=>
try
const responseObj = JSON.parse("xx" + responseText);
console.log(responseObj);
catch(err)
console.error(err);
//do something other
, (status, statusText, xhr)=>
console.log("fail");
);
JQuery
slim 即简化版。比起普通版,少了Ajax和特效模块。
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script>
$.ajax(
url: 'http://jsonplaceholder.typicode.com/users/',
type: 'GET',
dataType: 'json',
timeout: 500, //0 for no timeout
async: true, //默认是异步
data:
,
success: (data, textStatus, jqXHR)=>
console.log(data); //数据会被转为object或array
console.log(textStatus); //成功一般返回success
console.log(jqXHR);
,
error: (XMLHttpRequest, textStatus, errorThrown)=>
console.log(XMLHttpRequest);
console.log(textStatus);
console.log(errorThrown);
);
成功的情况
数据 data 会被转为 object 或 array,而 textStatus 一般会是 “success”。
注意 jqXHR 指的是 JQuery 自己封装的 XMLHttpRequest,是一个 Object。
失败的情况
如果访问了一个不存在(或者失效)的地址
- 当 timeout 参数值设的太小的时候,textStatus 和 errorThrown 都会返回 timeout
- 时间足够(或 不设超时,即timeout 设为 0)的时候,textStatus 会被赋值为“error”,errorThrown会被赋值为 “Not Found”(也就是 statusText 的值)
Zepto
Zepto最初是为移动端开发的库,是jQuery的轻量级替代品,因为它的API和jQuery相似,而文件更小(即使是简化版的 jquery.slim.min 也比 zepto.min 大了一倍)
Zepto最大的优势是它的文件大小,只有8k多,是目前功能完备的库中最小的一个,尽管不大,Zepto所提供的工具足以满足开发程序的需要。大多数在jQuery中·常用的API和方法Zepto都有,Zepto中还有一些jQuery中没有的。
另外,因为Zepto的API大部分都能和jQuery兼容,所以用起来极其容易,如果熟悉jQuery,就能很容易掌握Zepto。你可用同样的方式重用jQuery中的很多方法,也可以方面地把方法串在一起得到更简洁的代码,甚至不用看它的文档。
<script src="https://cdn.bootcss.com/zepto/1.2.0/zepto.min.js"></script>
<script>
$.ajax(
url: 'http://jsonplaceholder.typicode.com/users',
type: 'GET',
dataType: 'json',
timeout: 500, //0 for no timeout
async: true, //默认是异步
data:
,
success: (data, status, xhr)=>
console.log(data); //数据会被转为object或array
console.log(status); //成功一般返回success
,
error: (xhr, errorType, error)=>
console.log(xhr);
console.log(errorType);
console.log(error);
);
</script>
成功的情况
数据 data 会被转为 object 或 array,而 status 一般会是 “success”
失败的情况
如果访问了一个不存在(或者失效)的地址
- 当 timeout 参数值设的太小的时候,errorType 会被赋为 timeout,而 error 的值为 null【注意:这里与 JQuery 不一样】
- 时间足够(或 不设超时,即timeout 设为 0)的时候,errorType会被赋值为“error”,error 会被赋值为 “Not Found”(也就是 statusText 的值)
axios
vue2 已经不再维护 vue-resource 这个插件了,而改用基于 Promise 的 axios 插件了。
通过对象指定请求方式的 axios
<script src="https://cdn.bootcss.com/axios/0.19.0-beta.1/axios.min.js"></script>
<script>
axios(
url: 'http://jsonplaceholder.typicode.com/users/fff',
type: 'GET',
responseType: 'json', //这里jquery和zepto用的是dataType
data:
).then(response=>
console.log(response);
).catch(error=>
console.log(error);
);
</script>
成功的情况
失败的情况
速度慢的问题
速度慢是由于中间多发送了一个 OPTIONS 请求。正常情况下,它返回的状态码会被赋为 204,表示服务器收到请求,但返回体为空。
OPTIONS 请求方法的主要用途有两个:
- 获取服务器支持的HTTP请求方法;
- 用来检查服务器的性能。
304 的含义:
当一个客户端(通常是浏览器)向web服务器发送一个请求,如果web服务器返回304响应,则表示此请求的本地缓存是最新的,可以直接使用。这种方法可以节省带宽,避免重复响应。
3个请求的含义:
- 根据脚本地址,获取 axios 脚本
- 发送 OPTIONS 请求,获取服务器支持的 HTTP 请求方法
- 获取指定URL的JSON数据
直接指定请求方式的 axios
axios.get('http://jsonplaceholder.typicode.com/users/',
params:
).then((response)=>
console.log(response);
).catch((error)=>
console.log(error);
);
可以看到直接指定了 axios 的请求方法之后,就不再发送 OPTIONS 请求了。
fetch
fetch 与 jQuery.ajax() 主要有几点不同:
- 当接收到一个代表错误的 HTTP 状态码时,从 fetch()返回的 Promise 不会被标记为 reject, 即使该 HTTP 响应的状态码是 404 或 500。相反,它会将 Promise 状态标记为 resolve (但是会将 resolve 的返回值的 ok 属性设置为 false ),仅当网络故障时或请求被阻止时,才会标记为 reject。
- 默认情况下,fetch 不会从服务端发送或接收任何 cookies, 如果站点依赖于用户 session,则会导致未经认证的请求(要发送 cookies,必须设置 credentials 选项)。
var myHeaders = new Headers();
fetch(url,
method: 'GET',
headers: myHeaders,
credentials: "include"
)
- fetch不支持JSONP。fetch是与服务器端进行异步交互的,而JSONP是外链一个javascript资源,并不是真正ajax,所以fetch与JSONP没有什么直接关联,当然至少目前是不支持JSONP的。
fetch('http://jsonplaceholder.typicode.com/users/fff')
.then(response=>
console.log(response);
return response.json();
, err=>
console.error(err);
).then(myJson=>
console.log(myJson);
);
成功的情况
失败的情况
-
访问了一个不存在的地址
fetch 判断是否成功的依据是能否连的上服务器并收到数据。因此需要额外的代码来判断是否是获取错误(错误的情况,response.json() 会返回空对象)
-
找不到服务器的情况
只有在找不到服务器,没有收到应答的情况,才会走到 error 函数,否则都会触发success函数。
另外,不管有没有错误发生,后续的then都会被调用。但由于后面 then 函数的参数是前面 then 函数的返回值,由于出错这里是 undefined,否则是空对象()。
以上是关于Javascript 中 ajax 和 axiosfetch 的区别的主要内容,如果未能解决你的问题,请参考以下文章