前端请求数据主要有XMLHttpRequest(XHR)、ajax、axios、fetch等方式。
原生xhr请求
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'json';
xhr.onload = function() {
console.log(xhr.response);
};
xhr.onerror = function() {
console.log("Oops, error");
};
xhr.send();
ajax请求
//post请求
$.ajax({
type: 'POST',
url: url路径,
data: data,
dataType: dataType,
success: function (data) {
console.log(data)
},
error: function () {}
});
//get请求
$.ajax({
type: 'GET',
url: url路径,
data: data,
dataType: dataType,
success: function (data) {
console.log(data)
},
error: function () {}
});
axios请求
axios({
method: 'post', //或者 method: 'get',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
fetch请求
fetch(url).then(function(response) {
return response.json();
}).then(function(data) {
console.log(data);
}).catch(function(e) {
console.log("Oops, error");
});
使用 ES6 的 箭头函数 后:
fetch(url).then(response => response.json())
.then(data => console.log(data))
.catch(e => console.log("Oops, error", e))
这种 Promise 的写法还是有 Callback 的影子,而且 promise 使用 catch 方法来进行错误处理的方式有点奇怪。不用急,下面使用 async/await 来做最终优化,async/await 是非常新的 API,属于 ES7,目前尚在 Stage 1(提议) 阶段。使用 Babel 开启 runtime 模式后可以把 async/await 无痛编译成 ES5 代码。也可以直接使用 regenerator 来编译到 ES5
try {
let response = await fetch(url);
let data = response.json();
console.log(data);
} catch(e) {
console.log("Oops, error", e);
}
// 注:这段代码如果想运行,外面需要包一个 async function
fetch('/users.json', {
method: 'post',
mode: 'no-cors',
data: {}
}).then(function() { /* handle response */ });
对上述方法的理解:
ajax是对原生XHR的封装,除此以外还增添了对JSONP的支持。优点很多,缺点的话:
- 本身是针对MVC的编程,不符合现在前端MVVM的浪潮
- 基于原生的XHR开发,XHR本身的架构不清晰,已经有了fetch的替代方案
- JQuery整个项目太大,单纯使用ajax却要引入整个JQuery非常的不合理(采取个性化打包的方案又不能享受CDN服务)
看法:尽管JQuery对我们前端的开发工作曾有着(现在也仍然有着)深远的影响,但随着VUE,REACT新一代框架的兴起,以及ES规范的完善,更多API的更新,JQuery这种大而全的JS库,未来的路会越走越窄。
axios是在Vue2.0之后被尤雨溪推荐用替换JQuery ajax来使用的,Axios本质上也是对原生XHR的封装,只不过它是Promise的实现版本,符合最新的ES规范。从其官网可看出其特性:
- 从 node.js 创建 http 请求
- 支持 Promise API
- 客户端支持防止CSRF
- 提供了一些并发请求的接口(重要,方便了很多的操作)
注:支持防止CSRF就是让你的每个请求都带一个从cookie中拿到的key, 根据浏览器同源策略,假冒的网站是拿不到你cookie中得key的,这样,后台就可以轻松辨别出这个请求是否是用户在假冒网站上的误导输入,从而采取正确的策略。
优点:
- 提供了并发的封装
- 没有下文会提到的fetch的各种问题
- 体积也较小
看法:当之无愧是现在最应该选用的请求的方式。
fetch号称是AJAX的替代品,它的好处:
- 符合关注分离,没有将输入、输出和用事件来跟踪的状态混杂在一个对象里
- 更好更方便的写法
不管是Jquery还是Axios都已经帮我们把xhr封装的足够好,使用起来也足够方便,我们还要花费大力气去学习fetch主要是其主要优势:
- 更加底层,提供的API丰富(request, response)
- 脱离了XHR,是ES规范里新的实现方式
但是,正因为fetch是一个低层次的API,你可以把它考虑成原生的XHR,所以使用起来并不是那么舒服,需要进行封装。还有一些其他具体问题,如:
- Fetch 请求默认是不带 cookie 的,需要配置项,设置
fetch(url, {credentials: 'include'})
- fetch只对网络请求报错,对400,500都当做成功的请求,需要封装去处理
- fetch不支持abort,不支持超时控制,使用setTimeout及Promise.reject的实现的超时控制并不能阻止请求过程继续在后台运行,造成了流量的浪费
- fetch没有办法原生监测请求的进度,而XHR可以
fetch在前端的应用上有一项xhr怎么也比不上的能力:跨域的处理 fetch中可以设置mode为"no-cors"(不跨域)
看法:现在发展的还不是很完善,不大好用。
注:
1.大家也可以看看:https://segmentfault.com/a/1190000012836882
2.ajax的原理:相当于在用户和服务器之间加了—个中间层,使用户操作与服务器响应异步化。这样把以前的一些服务器负担的工作转嫁到客户端,利于客户端闲置的处理能力来处理,减轻服务器和带宽的负担,从而达到节约ISP的空间及带宽租用成本的目的。
3.xml和json,在ajax交互中,哪一种更易于开发和维护,js中怎么序列化JSON字符串?
json相比xml可读性和可扩张性好、编码及解码难度较低、在数据交互中带宽占用少,并且在当下是最流行的数据交互格式。
序列化JSON字符串:eval() 或者 JSON.parse()
4.总结一下目前接触到的前后端交互的方法:
- xhr
- ajax
- request--------nodejs
- vue-resourse
- axios
- fetch
- mui.ajax
- wx.request
- $http