网络模块的选择
传统的Ajax是基于XMLHttpRequest(XHR),为什么不用它呢?
因为它的配置和调用方式等非常混乱,编码起来非常繁琐,所以真实开发中很少直接使用,而是使用jQuery-Ajax。
在前面的学习中, 我们经常会使用jQuery-Ajax,相对于传统的Ajax非常好用,为什么不选择它呢?
首先,我们先明确一点,在Vue的整个开发中都是不需要使用jQuery了,那么就意味着为了方便我们进行一个网络请求, 特意引用一个jQuery这显然是不合理的,完全没有必要为了用网络请求就引用这个重量级的框架。
官方在Vue1.x的时候,推出了Vue-resource,它的体积相对于jQuery小很多,又是官方推出的,为什么不选择它呢?
在Vue2.0退出后, Vue作者就在GitHub的Issues中说明了去掉vue-resource,并且以后也不会再更新,那么意味着以后vue-reource不再支持新的版本时,也不会再继续更新和维护,对以后的项目开发和维护都存在很大的隐患。
推荐的框架——axios
优点:
- 在浏览器中发送XMLHttpRequests请求
- 在node.js中发送http请求
- 支持Promise API
- 拦截请求和响应
- 转换请求和相应数据
- …
jsonp
在前端开发中,我们一种常见的网络请求方式就是JSONP,使用JSONP最主要的原因往往是为了解决跨域访问的问题,那么JSONP的原理是什么呢?
JSONP的核心在于通过script标签的src来帮助我们请求数据。
原因是我们的项目部署在domain1.com服务器上时,是不能直接访问domain2.com服务器上的资料的。
这个时候,我们利用script标签的src帮助我们去服务器请求到数据,将数据当做一个javascript的函数来执行,并且执行的过程中传入我们需要的json。
所以,封装jsonp的核心就在于我们监听window上的jsonp进行回调时的名称。
JSONP如何封装呢?
let count = 1;
export default function originPJSONP (option) {
// 1. 从传入的option中提取URL
const url = option.url;
// 2. 在body中添加script标签
const body = document.getElementsByTagName('body')[0];
const script = document.createElement('script);
// 3. 内部生成一个不重复的callback
const callback = 'jsonp' + count++
// 4. 监听window上的jsonp调用
return new Promise((resolve, reject) => {
try {
window[callback] = function (result) {
body.removeChild(script);
resolve(result);
}
const params = handleParam(option.data);
script.src = url + '?callback=' + callback + params;
body.appendChild(script);
} catch (e) {
body.removeChild(script);
reject(e);
}
})
}
funciton handleParam (data) {
let url = '';
for (let key in data) {
let value = data[key] !== undefinded ? data[key] :
url += '&${key}=${encodeURIComponent(value)}'
}
return url
}