原生JS请求

现代浏览器,最开始与服务器交换数据,都是通过XMLHttpRequest对象。它可以使用JSON、XML、HTML和text文本等格式发送和接收数据。

首先我们先把原生的请求封装一下:

xmlhttp=new XMLHttpRequest()
function obj2str(data) {
data = data || {}; // 如果没有传参, 为了添加随机因⼦,必须⾃⼰创建⼀个对象
data.t = new Date().getTime();
var res = [];
for (var key in data) {
//在URL中是不可以出现中⽂的,如果出现了中⽂需要转码,可以调⽤encodeURIComponent⽅法,URL中
res.push(encodeURIComponent(key) + "=" + encodeURIComponent(data[key]));
}
return res.join("&");
}

function ajax(option) {
var str = obj2str(option.data);//key=value&key=value;
var xmlhttp, timer;
if (option.type.toLowerCase() === "get") {//toLowerCase将⼤写转化为⼩写
xmlhttp.open(option.type, option.url + "?" + str, true)
xmlhttp.send();
} else {
xmlhttp.open(option.type, option.url, true);
//注意点:以下代码必须放在open和send之间
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send(str);
}
xmlhttp.onreadystatechange = function (ev2) {
if (xmlhttp.readyState === 4) {
clearInterval(timer);
//判断是否请求成功(Http状态码⼤于等于200,且⼩于300,和状态码等于304为请求成功)
if (xmlhttp.status >= 200 && xmlhttp.status < 300 || xmlhttp.status === 304) {
option.success(xmlhttp);
} else {
option.error(xmlhttp);
}
}
};
if (option.timeout) {
timer = setInterval(function () {
console.log("中断请求");
xmlhttp.abort();
clearInterval(timer);
}, option.timeout);
}
}

使用:

ajax({
url:"http://server-name/login",
type:'post',
data:{
username:'username',
password:'password'
},
dataType:'json',
timeout:10000,
contentType:"application/json",
success:function(data){
      。。。。。。//服务器返回响应,根据响应结果,分析是否登录成功
},
//异常处理
error:function(e){
console.log(e);
}
})

优点:

  1. 不重新加载页面的情况下更新网页
  2. 在页面已加载后从服务器请求/接收数据
  3. 在后台向服务器发送数据。

缺点:

  1. 使用起来也比较繁琐,需要设置很多值。
  2. 早期的IE浏览器有自己的实现,这样需要写兼容代码。

Jq中的ajax:

为了更快捷的操作DOM,并且规避一些浏览器兼容问题,产生了​​jQuery​​​。它里面的​​AJAX​​​请求也兼容了各浏览器,可以有简单易用的方法​​$.get​​​,​​$.post​​​。简单点说,就是对​​XMLHttpRequest​​对象的封装。

$.ajax({
type: 'POST',
url: url,
data: data,
dataType: dataType,
success: function () {},
error: function () {}
})

优点

  1. 对原生​​XHR​​的封装,做了兼容处理,简化了使用。
  2. 增加了对​​JSONP​​的支持,可以简单处理部分跨域。

缺点

  1. 如果有多个请求,并且有依赖关系的话,容易形成回调地狱。
  2. 本身是针对MVC的编程,不符合现在前端MVVM的浪潮。
  3. ajax是jQuery中的一个方法。如果只是要使用ajax却要引入整个jQuery非常的不合理。

Axios:

​Axios​​​是一个基于​​promise​​​的​​HTTP​​​库,可以用在浏览器和 ​​node.js​​​ 中。它本质也是对原生​​XMLHttpRequest​​的封装,只不过它是Promise的实现版本,符合最新的ES规范。

axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'liu',
lastName: 'weiqin'
}
})
.then(res => console.log(res))
.catch(err => console.log(err))

优点

  1. 从浏览器中创建​​XMLHttpRequests​
  2. 从​​node.js​​​ 创建​​http​​ 请求
  3. 支持​​Promise​​ API
  4. 拦截请求和响应
  5. 转换请求数据和响应数据
  6. 取消请求
  7. 自动转换​​JSON​​ 数据
  8. 客户端支持防御​​XSRF​

缺点

  1. 只持现代代浏览器.

fetch:

​Fetch API​​​提供了一个 ​​JavaScript​​​ 接口,用于访问和操作​​HTTP​​​管道的部分,例如请求和响应。它还提供了一个全局​​fetch()​​​方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源。
​​​fetch​​​是低层次的API,代替​​XHR​​​,可以轻松处理各种格式,非文本化格式。可以很容易的被其他技术使用,例如​​Service Workers​​​。但是想要很好的使用​​fetch​​,需要做一些封装处理。

fetch('http://example.com/movies.json')
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(myJson);
});

fetch目前遇到的问题

  1. ​fetch​​​只对网络请求报错,对​​400​​​,​​500​​都当做成功的请求,需要封装去处理
  2. ​fetch​​​默认不会带​​cookie​​,需要添加配置项。
  3. ​fetch​​​不支持​​abort​​​,不支持超时控制,使用​​setTimeout​​​及​​Promise.reject​​的实现超时控制并不能阻止请求过程继续在后台运行,造成了流量的浪费。
  4. ​fetch​​​没有办法原生监测请求的进度,而​​XHR​​可以。
请注意,fetch规范与jQuery.ajax()主要有两种方式的不同,牢记:

-. 当接收到一个代表错误的 HTTP 状态码时,从 fetch()返回的 Promise 不会被标记为 reject, 即使该 HTTP 响应的状态码是 404 或 500。相反,它会将 Promise 状态标记为 resolve (但是会将 resolve的返回值的 ok 属性设置为 false ),仅当网络故障时或请求被阻止时,才会标记为 reject。

-. 默认情况下,fetch 不会从服务端发送或接收任何 cookies, 如果站点依赖于用户 session,则会导致未经认证的请求(要发送 cookies,必须设置 credentials 选项)。

 

 

长风破浪会有时,直挂云帆济沧海