12 网络模块的封装
常见的网络请求模块以及对比
- JSONP的原理和封装
- JSONP原理回顾
- JSONP请求封装
- axios的内容详解
- 认识axios网络模块
- 发送基本请求
- axios创建实例
- axios拦截器的使用
- JSONP的原理和封装
网络模块的选择:
Vue中发送网络请求有非常多的方式,开发中
选择一: 传统的Ajax是基于XMLHttpRequest(XHR)
为什么不用它呢?
非常好解释, 配置和调用方式等非常混乱.
编码起来看起来就非常蛋疼.
所以真实开发中很少直接使用, 而是使用jQuery-Ajax
选择二: 在前面的学习中, 我们经常会使用jQuery-Ajax
相对于传统的Ajax非常好用.
为什么不选择它呢?
首先, 我们先明确一点: 在Vue的整个开发中都是不需要使用jQuery了.
那么, 就意味着为了方便我们进行一个网络请求, 特意引用一个jQuery, 你觉得合理吗?
jQuery的代码1w+行.
Vue的代码才1w+行.
完全没有必要为了用网络请求就引用这个重量级的框架.
选择三: 官方在Vue1.x的时候, 推出了Vue-resource.
Vue-resource的体积相对于jQuery小很多.
另外Vue-resource是官方推出的.
为什么不选择它呢?
在Vue2.0退出后, Vue作者就在GitHub的Issues中说明了去掉vue-resource, 并且以后也不会再更新.
那么意味着以后vue-reource不再支持新的版本时, 也不会再继续更新和维护.
对以后的项目开发和维护都存在很大的隐患.
选择四: 在说明不再继续更新和维护vue-resource的同时, 作者还推荐了一个框架: axios,为什么不用它呢?
axios有非常多的优点, 并且用起来也非常方便.
12.1 jsonp
前端开发中, 我们一种常见的网络请求方式就是JSONP,使用JSONP最主要的原因往往是为了解决跨域访问的问题.
jsonp原理
JSONP的核心在于通过
<script>
标签的src来帮助我们请求数据.绕过同源政策的限制原因是我们的项目部署在domain1.com服务器上时, 是不能直接访问domain2.com服务器上的资料的.
这个时候, 我们利用
<script>
标签的src帮助我们去服务器请求到数据, 将数据当做一个javascript的函数来执行, 并且执行的过程中传入我们需要的json.所以, 封装jsonp的核心就在于我们监听window上的jsonp进行回调时的名称.

- jsonp请求的封装
- 没有promise的实现
1 | // 拼接参数 |
- 基于promise的实现
1 | // 拼接参数 |

12.2 axios框架
12.2.1 认识axios网络模块
- Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
- 特性:
- 从浏览器中创建 XMLHttpRequests
- 从 node.js 创建 http 请求
- 支持 Promise API
- 拦截请求和响应
- 转换请求数据和响应数据
- 取消请求
- 自动转换 JSON 数据
- 客户端支持防御 XSRF
- 使用axios(axios是http库的框架,需要下载库文件并且导入才能使用)
- 下载(npm的方式)
$ npm i axios --save
开发依赖
- 导入axios
- 使用axios
- 下载(npm的方式)
axios API详细解析
axios(config)
通过axios传递相关配置来创建请求
axios中config选项
- config是一个对象
1
2
3axios({
请求配置信息
})注意请求配置信息中get请求属性->params,post请求->data属性
1 | // 发送 POST 请求 |
axios(url[, config])
- []表示是可选的
- 发送get请求
1 | axios('/user/123',{请求配置信息}) |
请求方法的别名
- axios.request(config)
- axios.get(url[, config])
- axios.delete(url[, config])
- axios.head(url[, config])
- axios.options(url[, config])
- axios.post(url[, data[, config]])
- axios.put(url[, data[, config]])
- axios.patch(url[, data[, config]])
处理并发请求
- axios.all(iterable),类似于promise.all
- axios.spread(callback),直接通过回调函数的方式获取返回值数组中的数值通过实参接收
创建实例
- 可以使用自定义配置新建一个 axios 实例,比如在不同的baseurl中发送请求,就可以单独创建实例
axios.create()
1 | const instance = axios.create({ |
实例方法
以下是可用的实例方法。指定的配置将与实例的配置合并。
axios#request(config)
axios#get(url[, config])
axios#delete(url[, config])
axios#head(url[, config])
axios#options(url[, config])
axios#post(url[, data[, config]])
axios#put(url[, data[, config]])
axios#patch(url[, data[, config]])
请求配置包括
- 这些是创建请求时可以用的配置选项。只有
url
是必需的。如果没有指定method
,请求将默认使用get
方法。 - 注意在使用别名方法时,
url
、method
、data
这些属性都不必在配置中指定。
1 | { |
响应配置
- 某个请求的响应包含以下信息
1 | { |
- 使用
then
时,你将接收下面这样的响应 :
1 | axios.get('/user/12345') |
- 在使用
catch
时,或传递 rejection callback 作为then
的第二个参数时,响应可以通过error
对象可被使用,正如在错误处理这一节所讲。
配置默认值
- 你可以指定将被用在各个请求的配置默认值
全局的 axios 默认值
1 | axios.defaults.baseURL = 'https://api.example.com'; |
自定义实例默认值
1 | // Set config defaults when creating the instance |
配置的优先顺序
配置会以一个优先顺序进行合并。这个顺序是:在 lib/defaults.js
找到的库的默认值,然后是实例的 defaults
属性,最后是请求的 config
参数。后者将优先于前者。
1 | // 此时超时配置的默认值是 `0` |
拦截器
- 在请求或响应被
then
或catch
处理前拦截它们。 - 请求拦截:
axios.interceptors.request.use(function(config){},function(err)}{})
- 响应拦截:
axios.interceptors.response.use(function(config){},function(err)}{})
- 注意:拦截之后的操作执行之后必须将拦截的内容返回才能执行后续的请求操作
1 | // 添加请求拦截器 |
- 移出拦截器
- 格式:
axios.interceptors.request.eject(拦截器)
- 格式:
1 | const myInterceptor = axios.interceptors.request.use(function () {/*...*/}); |
- 自定义 axios 实例添加拦截器
1 | const instance = axios.create(); |
12.2.2 发送基本请求
1 | // 1.axios的基本使用axios(config),返回值就是一个promise |
12.2.3 axios发送并发请求
我们可能需求同时发送两个请求
使用axios.all, 可以放入多个请求的数组.
axios.all([]) 返回的结果是一个数组,使用 axios.spread 可将数组 [res1,res2] 展开为 res1, res2
1 | // 5.axios发送并发请求,和promise.all类似 |
12.2.4 axios创建实例和设置默认配置
- 设置默认配置(全局)
1 | // 4.使用全局的axios对默认的服务器地址进行默认设置,此时在写utl中就不用了写baseUel,注意设置一定要提前设置 |
当项目部署在多个服务器上时,此时就不能设置全局默认配置,
- 解决方案
- 通过异步框架的网站服务器Nginx
- 通过创建axios实例,在实例对象中单独设置baseUrl
- 创建实例:
const instance = axios.create(config)
, - 调用实例对象:
instance(config)
,和axios的调用一样
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27// 当项目部署在多个服务器时(涉及到异步框架的网页服务器Nginx,作为中间的代理服务器分发出去),此时的baseUrl是不一致的,这是后就不能设置全局的baseUrl,解决方案:通过创建axios的实例,在每个实例中设置,此时创建的每个实例的用法和axios一样
const instance = axios.create({
baseURL: 'http://123.27.32.32:8000',
timeout: 5000
})
instance({
url: '/home/multidata',
params: {
type: 'pop',
page: 1
}
}).then((res) => {
console.log(res);
})
const instance2 = axios.create({
baseURL: 'http://123.27.32.32:8000',
timeout: 5000
})
instance2({
url: '/home/multidata',
params: {
type: 'pop',
page: 1
}
}).then((res) => {
console.log(res);
})- 解决方案
12.2.5 axios的封装
解决的问题:在使用axios的时候封装在进行代码重构时方便重构,封装的方式如下
方式1:传递两个回调函数
- 封装:在src下面创建network->request.js
- require(config,success,error)
- config(对象,success(回调函数,error(回调函数)))
- require(config,success,error)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import axios from 'axios'
export function request(config, success, error) {
// instance返回的promise,axios支持promise,创建axios实例对象
const instance = axios.create({
baseURL: 'http://123.207.32.32:8000',
timeout: 5000
});
// 发送请求
instance(config).then(res => {
// 通过回调函数的方式将返回值获取,回调函数在使用时自定义,通过参数拿到返回值
success(res);
}).catch(err => {
error(err);
})
}- 使用:导入直接使用
1
2
3
4
5
6
7
8
9
10
11import { request } from "./network/request";
request({
url: '/home/multidata'
}, (res) => {
// success函数,通过res接收参数
console.log(res);
}
, err => {
//error函数
console.log(err);
})方式2:在config中传入两回调函数作为参数
- 封装:在src下面创建network->request.js
- request(config)
- config:baseConfig(对象),success(回调函数),error(回调函数)
- request(config)
1
2
3
4
5
6
7
8
9
10
11
12import axios from 'axios'
export function request(config) {
const instance = axios.create({
baseURL: 'http://123.207.32.32:8000',
timeout: 5000
});
instance(config.baseConfig).then(res => {
config.success(res)
}).catch(err => {
config.error(err)
})
}- 使用
1
2
3
4
5
6
7
8
9
10
11
12
13import { request } from "./network/request";
request({
baseConfig: {
url: '/home/multidata'
},
success: function (res) {
// success函数,通过res接收参数
console.log(res);
},
error: function (err) {
console.log(err);
}
})方式3:返回promise对象
- 封装:在src下面创建network->request.js
- axios执行的异步操作,将异步操作包裹在promise对象中获取去返回值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import axios from 'axios'
// 封装方式3(promise方式将异步执行包裹在promise内部,通过then和catch接收响应结果)
export function request(config) {
return new Promise((resolve, reject) => {
const instance = axios.create({
baseURL: 'http://123.207.32.32:8000',
timeout: 5000
});
instance(config).then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
}- 使用封装:通过then和catch来自动执行resolve()和reject
1
2
3
4
5
6
7request({
url: '/home/multidata'
}).then(res => {
console.log(res);
}).catch(err => {
console.log(err);
})方式4:直接返回promise(推荐使用这种)
- 封装:在src下面创建network->request.js
- axios的实例对象返回的本身就是promise对象,不需要再次封装,直接返回
1
2
3
4
5
6
7
8
9
10
11export function request(config) {
// 1.创建axios实例对象
const instance = axios.create({
baseURL: 'http://123.207.32.32:8000',
timeout: 5000
});
// 拦截器内容在拦截器的使用部分
// 发送请求
return instance(config)
}- 使用,和方式3一样
- 封装:在src下面创建network->request.js
12.2.4 axios拦截器的使用
- axios提供了拦截器,用于我们在发送每次请求或者得到相应后,进行对应的处理。
- 注意在每次拦截的时候,操作执行完毕需要将拦截 的内容return后续请求才会执行
1 | // 2.1 请求拦截器的作用 |
请求拦截器的可以做的事情:
- 比如config中的一些信息不符合服务器的要求
- 比如每次发送网络请求时, 都希望在界面中显示一个请求的图标
- 某些网络请求(比如登录(token)), 必须携带一些特殊的信息
请求拦截中错误拦截较少,通常都是配置相关的拦截
可能的错误比如请求超时,可以将页面跳转到一个错误页面中。
响应拦截中完成的事情:
- 响应的成功拦截中,主要是对数据进行过滤。
- 响应的失败拦截中,可以根据status判断报错的错误码,跳转到不同的错误提示页面。
拦截器参数:参数1:正确拦截函数;参数2:错误拦截函数
1 | axios.interceptors.response/request.use(正确拦截回调函数,错误拦截回调函数) |
12.3 axios和vue/react框架的整合
vue-axios
- 基于vue的axios的封装
vue-axios-plugin
- vuejs项目的axios插件
react-axios
- 适用于react框架的Axios 组件, 具有 child function callback.
在render阶段进行异步请求。
13 前端安全
13.1 xss
13.2 CSRF攻击
13.3 Nginx异步框架网站服务器
知识点补充
前端交互概述
接口调用的方式有哪些
原生ajax
基于jQuery的ajax
Fetch调用:ajax+promise的使用,fetch的接口返回值是promise
Promise:结局了异步深层嵌套
axios接口:接口返回值也是promise
url 地址格式有哪些
传统的url
Restful形式的url
fetch API使用
- fetch 就是 ajax + Promise. 使用的方式和 jquery 提供的 $.ajax() 差不多
- fetch默认是get请求
- 详细使用查看此链接MDN
本文链接: https://sparkparis.github.io/2020/05/16/Vue%E7%AC%94%E8%AE%B09/
版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!