当前位置 博文首页 > m0_45291815的博客:axios-ajax-WebSocket紧急救援
终止请求:abort()
一个简单的ajax,仅供入门学习使用
/**
* 调用SendAjax,调用接口
* @param {obj} object method:请求方式,url:地址,success:请求成功回调
*/
function SendAjax (obj) {
function createAJAX () {
let ajax = null
if (window.XMLHttpRequest) {
ajax = new XMLHttpRequest() // iE7以上
} else if (window.ActiveXObject) {
const ActiveXObject = window.ActiveXObject // iE6到iE5以下
ajax = new ActiveXObject('Microsoft.XMLHTTP')
} else {
alert('请升级浏览器')
}
return ajax
}
var ajax = createAJAX() // 创建一个ajax对象
ajax.open(obj.method, obj.url, true)
ajax.onreadystatechange = function () {
if (ajax.readyState === 4 && ajax.status === 200) {
obj.success(ajax.responseText)
}
}
if (obj.method === 'get') {
ajax.send(null)
} else if (obj.method === 'post') {
ajax.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
let str = ''
let v = ''
let f = false
for (var attr in obj.data) {
str += v + attr + '=' + obj.data[attr]
v = '&'
if (obj.data[attr] !== '') {
f = true
} else if (obj.data[attr] === '') {
f = false
return f
}
}
if (f) {
ajax.send(str)
}
}
}
export default SendAjax()
跨越:协议,域名,端口号不同,引发的安全请求问题
img
标签的src
可以解决上面的问题,但是请求回来的是图片信息,不能使用
同理还有video
标签等等
script
标签的src请求回来的是js代码信息,可以作为跨越解决方案
但是返回的信息如何获取?可以通过函数调用的方式获取,调用函数,传入入参
script
标签script
标签前进给bodycallback(数据信息)
的形式返回给浏览器// 粗劣残暴的解决方案
// params可以优化成对象
/**
* param { url } 跨越请求的地址
* param { params } 拼接的字符串入参
* param { fn } 获取返回结果的回调
*/
export default function jsonp(url, params, fn) {
let callbackName = `fn${+new Date()}`
window[callbackName] = (res) => { fn(res) }
let script = document.createElement('script')
script.type = "text/javascript";
script.src = `${url}?callback=${callbackName}&${params}`
document.body.appendChild(script)
document.body.removeChild(script)
}
实现功能:
post
请求,get
请求等基本请求
请求前拦截,请求后拦击
设置全局devServe
识别标志(baseUrl
),设置全局timeout
响应时间
拦截前操作:
添加全部baseUrl
,可以单独接口自定义
添加全部timeout
,可以单独接口自定义
通过store
获取token
,添加全局token
,可以单独接口不需要定义
可以通过接口单独定义,将参数转表单格式
可以通过接口单独定义,设置下载文件名称
可以通过接口单独定义,添加获取下载/上传进度条的构造函数
创建接口关闭对象,并添加到store
的api
请求控制队列 ----(?:未设计和验证)
为了在切换路由时或特别情况时主动中断请求
请求后拦截:
请求成功后将当前接口对象从api
请求控制队列删除
判断接口数据是否为二进制图片流数据:是,就return
二进制流转图片的链接
统一错误处理函数: ---- (?需要自己设置)
判断是否为未登录: ---- (?需要自己设置)
是:统一报错,return false
,并调整到登录页面
判断后端返回的状态码是否通过判断: ---- (?需要自己设置)
是:返回结果,return data
否:进入下一步
未通过判断,是否存在单独设置获取错误表示
是:return Promise.reject(data)
否:进行统一报错,return false
post
请求形式下载
get
请求形式下载
post
转表单形式下载
json
转xlsx
下载功能
post
文件和数据分开上传
post
文件和数据合成formData
一起上传
xlsx
转json
导入功能
可以直接复制,建议将代码看完后,修给后使用
import axios from 'axios'
import Qs from 'qs' // axios携带的插件,无序再次下载
import XLSX from 'xlsx' // xlsx需要下载 npm install --save-dev xlsx
import store from './store' // 引入vuex或redux或models 的数据管理
/**
* @params { timeout } number 请求超时时间,默认15s
* @params { preFix } string 请求前缀,process.env.NODE_ENV === 'development' ? '/api' : '/gateway', 默认/api
* @params { Message } function 错误统一处理函数, 参1:返回错误信息,参2:是否为未登录(默认false)
* @params { baseURL } string 接口域名端口设置,默认空
* @returns { ajax } object 返回接口请求对象
* ajax对象, post, get, delete, patch 请求
* export const a = (params) => ajax.post('/url', {
* ...params,
* baseUrl: '是否自定义前缀(如:/api),string'
* withoutToken: '是否添加token,boolean',
* transform: '是否转换为表单请求,boolean',
* timeout: '单独设置请求超时时间',number, 默认空
* setFileName: '自定义文件下载名称, string'
* getRange: 获取进度条(上传下载):Object: fn:回调函数,type判断上传upload还是下载download
* 而且需要后端进行相关处理,否则获取不到文件大小total
*
* gainError: '是否单独处理错误信息(会进行传递),boolean'
* })
* 文件下载和请求一样
* ajax.downloadFileByPost post请求下载文件
* ajax.downloadFileByGet get请求下载文件
* ajax.downloadFileByForm 表单请求下载文件
* @params { JsonData } json json数据格式
* @params { columns } object 设置xlsx表头枚举
* @params { FileName } 下载xlsx文件名称
* ajax.jsonToXlsx json数据转xlsx(最简单的表格)下载 // 待验证
* ajax.jsonToXlsx(JsonData, columns, FileName)
*
* 文件上传
* @params { url, file, data }
* ajax.uploadFile 文件上传 文件和数据分开
* @params { url, params }
* ajax.uploadFileWithPost 文件上传 文件和数据不分开
* @params { file } file 上传的excel文件
* @params { columns } json excel解析替换标题
* columns = [
{ label: '姓名', key: 'name' },
{ label: '电话', key: 'phone' },
{ label: '邮箱', key: 'email' }
]
* ajax.xlsxToJson xlsx转json导入数据
*
* 获取上传文件方式
* 1、原生
* input type='file' @change=getFiles($event)
* getFiles () { console.log(e.target.files) } 此时就可以拿到文件数据
* 2、element
<el-upload
action="" // 请求地址设空
accept=".xls,.xlsx"
:auto-upload="false" // 禁止上传就请求
:on-change="handleChange" // 通过on-change回调函数获取文件数据
/>
handleChange (file) { this.file = file || null }
* 3、ant design
* 查看ant design 上传文档-手动上传
beforeUpload (file) {
this.setState(state => { fileList: [ ...fileList, file ] })
return false // 返回false,终止自动上传
}
* 4、vant
文件上传完毕后会触发 after-read 回调函数,获取到对应的 file 对象
* 5、taro
* 6、小程序
* 使用小程序自带的上传组件
*
* @params { word } 终止返回文字提示
* ajax请求中断 // 待验证
* ajax.cancelAjax(word)
*/
/* 使用实例
const require = setAjax({
timeout: 1000 * 60 * 10,
preFix: '/api',
Message: (msg, notLoading) => {},
baseUrl: 127.0.0.1:8800
})
*/
function setAjax ({ timeout, preFix, Message, baseURL }) {
/*
* 基础请求get post delete patch
* 通过请求拦截获取请求config,进行一下配置
* 1、配置响应响应超时时间timeout
* 2、配置不同情况下的请求地址baseUrl
* 3、配置不同情况下的请求头headers
*/
// 通过node变量,判断添加接口代理标志前缀
// 其中/api是webpack-serve代理服务器的判别前缀,拥有代理
// 另一个是后端的接口接入网关配置
const prefix = preFix || '/api'
const ajax = axios.create() // 实例化一个axios
ajax.defaults.timeout = timeout || 1000 * 15 // 设置默认请求超时时间
ajax.defaults.baseURL = baseURL || '' // 设置接口的地址和端口号
let setFileName = false // 自定义文件下载名称
// 添加代理识别/接口网关
function getBaseUrl (config) {
// 特定自定义过服务识别和网关接口,使用自定义的
if (config.data && config.data.baseUrl) {
config.url = config.data.baseUrl + config.url
delete config.data.baseUrl // 删除请求时不必要的属性
} else {
// 否则使用环境变量判断得到的
config.url = prefix + config.url
}
return config
}
// 添加token
function addToken (config) {
if (config.data.withoutToken) { // 如果注明不需要token,这不添加token,直接返回config对象
delete config.data.withoutToken // 删除请求时不必要的属性
return config
}
// 此时同步的是store里的token
if (store.state.token && !config.headers.Authorization) config.headers.Authorization = store.state.token // 添加token
return config
}
// 转换为表单格式请求
function switchToFormData (config) {
if (config.data && config.data.transform) { // 如果需要转换成表单格式
delete config.data.transform // 删除请求时不必要的属性
config.transformRequest = [ // 通过axios提供的transformRequest 修改入参格式
function (data) {
return Qs.stringify(data)
}
]
}
return config
}
// 单独设置超时时间
function setTimeOut (config) {
if (config.data && config.data.timeout) {
ajax.defaults.timeout = config.data.timeout
delete config.data.timeout
}
return config
}
// 设置下载文件名称
function setDownFileName (config) {
setFileName = false // 先重置下载文件名称
if (config.data && config.data.setFileName) { // 如果存在自定义下载文件名称
setFileName = config.data.setFileName
delete config.data.setFileName
}