网络模块封装
- jsonp
- axios
- axios的使用
- axios的配置
- 全局配置
- 常见配置
- 框架封装
- 拦截器
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) } }) } function handleParam(data) { let url = '' for (let key in data) { let value = data[key] !== undefined ? data[key] : '' url += `&${key}=${encodeURIComponent(value)}` } return url }
axios
axios的使用
-
为什么选择axios?
- 在浏览器中发送XMLHttpRequests请求
- 在node.js中发送http请求
- 支持PromiseAPI
- 拦截请求和响应
- 转换请求和响应数据
- 等等
-
支持多种请求方式:
- axios(config)
- axios.request(config)
- axios.get(url[, config])
- axios.delete(url[,config])
- axios.head(url[, config])
- axios.post(url[, data[, config]])
- axios.put(url[, data[, config]])
- axios.patch(url[, data[, config]])
-
安装axios
npm install axios --save
-
使用方式:
普通方式
axios({ //url: 'http://httpbin.org', // 测试网站 url: 'localhost://8000/menu/multidata', // 自定义一个springboot的服务器 method: 'get' // 指定提交方式,axios(context)不指定默认为get方式 }).then(result => { console.log(res) })
get / post方式
axios({ url: 'http://localhost:8000/menu/queryMenu', // 专门针对get请求的一个写法 params: { menuCode: '1' } }).then(result=>{ console.log(result); }) axios.post('http://localhost:8000/menu/addMenu',{ menuCode: 2, menuName: '我的', order: 2 }).then(() => { console.log('success'); }).catch(e=>{ console.log('error'); })
axios的配置
全局配置
-
在上面的实例中,我们的BaseUrl是固定的
- 事实上,在开发中很多参数都是固定的
- 这个时候我们可以进行一些抽取,也可以利用axios的全局配置
axios.defaults.baseURL = 'http://localhost:8000' axios.defaults.timeout = 50
常见配置
url、
method: get, post等
baseURL、
transformRequest:[function(data{})] 请求前数据处理、
transformResponse:[function(data){}]请求后数据处理
headers:['x-Request-With':'XMLHttpRequest']自定义的请求头、
params、
paramsSerializer:function(params){} 查询对象序列化函数、
data:{key:'aa'} request body、
timeout、
withCredentials 是否携带token、
adapter:function(resolve, reject, config){} 自定义请求处理、
auth: {userName: '', pwd:''} 身份验证的信息
responseType: '' 响应数据格式:json/blob/document/arraybuffer/texst/stream
框架封装
-
第一次封装:
- 将全局配置的"axios.defaults.baseURL = 'http://localhost:8000' "等配置项配置到单独的文件中去
新建network文件夹,创建index.js
import axios from "axios"; export function axiosX(config, success, failure) { const instance = axios.create({ // 创建axios实例,配置实例的默认配置 baseURL: 'http://localhost:8000', timeout: 5000 }) instance(config).then(res => success(res)).catch(err => failure(err)) }
上面的index.js是通过export一个方法出去,这个方法除了有之前写过的config之外,还传入两个方法,分别是作为成功和失败的回调函数。
main.js
import {axiosX} from "@/network"; axiosX({ url: '/menu/multidata' }, res => { console.log(res); }, err => { console.log(err); })
-
第二次封装:
- 之前时传入三个参数,这次我们只传入一个对象参数,但是这个对象包含了config和succ、err函数
index.js
import axios from "axios"; export function axiosX(config) { const instance = axios.create({ baseURL: 'http://localhost:8000', timeout: 5000 }) instance(config.baseConfig).then(res => { config.success(res) }).catch(err => { config.failure(err) }) }
main.js
import {axiosX} from "@/network"; const config = { baseConfig: { url: '/menu/multidata' }, success: function(res) { console.log(res) }, failure: function(err) { console.log(err); } } axiosX(config)
-
第三次封装Promise
- index中,返回Promise,直接在调用时通过then和catch方法处理
index.js
import axios from "axios"; export function axiosX(config) { return new Promise((resolve, reject) => { const instance = axios.create({ baseURL: 'http://localhost:8000', timeout: 5000 }) instance(config).then(res => { resolve(res) }).catch(err => { reject(err) }) }) }
main.js
import {axiosX} from "@/network"; axiosX({ url: '/menu/multidata' }).then(res => { console.log(res); }).catch(err => { console.log(err); })
但是由于我们instace(config)本身返回值就是一个Promise:
-
index.js的写法进一步优化:
import axios from "axios"; export default function axiosX(config) { const instance = axios.create({ baseURL: 'http://localhost:8000', timeout: 5000 }) instance(config) }
拦截器
-
axios提供了拦截器,用于我们在发送每次请求或者得到相应响应后,进行对应的处理。
- 请求拦截:
- config中的一些信息不符合服务器的要求
- 每次发送网络请求时,都希望在界面中显示一个请求的图标
- 某些网络请求(比如登录),必须携带一些特殊的信息token
- 响应拦截:
- 过滤我只想得到的信息
- 请求图标这个时候可以隐藏掉了
- 错误页面的跳转
- 请求拦截:
-
如何使用拦截器?
// 配置请求和响应拦截 instance.interceptors.request.use(config => { console.log('来到了request拦截success中'); return config }, err => { console.log('来到了request拦截failure中') return err }) instance.interceptors.response.use(response => { console.log('来到了ersponse拦截success中') return response.data }, err => { console.log('来到了response拦截failure中') return err })