封装ajax
ajax都不陌生,其核心是XMlHttpRequest。
用到的知识点
在使用ajax的时候,首先得new出一个XMLHttpRequest的实例对象, 在更早的ie6中我们使用window.ActiveXObject。
因此第一段代码这样写:
var Ajax ;
if (window.XMLHttpRequest) {
Ajax = new XMLHttpRequest();
} else if (window.ActiveXObject) {
Ajax = new ActiveXObject("Microsoft.XMLHTTP");
}
这样我们得到了一个,Ajax的实例。 为了方便使用,需要对这个实例对象的使用过程进行封装,方便之后的使用。
那么首先我们得知道他是怎么工作的: 这里推荐阅读MDN文档:AJAX;
大概过程是:
声明实例 -> 通过open初始化一个请求 -> setRequestHeader设置请求头 -> send发送请求->在onreadystatechange中监听状态发生变, readyState===4(方法调用完成), status === 200(请求状态成功)时,获取到数据(这里获取到的数据一般存在responseText中)。
值得注意的是:
1、setRequestHeader设置请求头 必须在open之后,send之前。
2、返回数据一般存在responseText中,如果请求头中,content-type为 'application/json' 那么需要转JSON。
需要记录的是:
- Ajax.readyState
- 代表请求状态的状态码
- Ajax.status
- 代表请求的响应状态
- Ajax.onreadystatechange
- 接收一个方法(当ajax的请求状态发生改变的时候都会触发)。
在这个函数中可以通过
this.redyState获取状态。
- 接收一个方法(当ajax的请求状态发生改变的时候都会触发)。
在这个函数中可以通过
- Ajax.open
- 初始化一个请求
- 参数:open(type,url+api,isAsync)
- Ajax.send
- 发送请求
- 参数 send(data || JSON.parse(data))
简单的封装过程
function ajax (sendObj){
let Ajax;
const baseUrl = 'http://127.0.0.1:9090' ;
if (window.XMLHttpRequest) {
Ajax = new XMLHttpRequest();
} else if (window.ActiveXObject) {
Ajax = new ActiveXObject("Microsoft.XMLHTTP");
}
const {type,api,data,headers,dataType,success,fail,complete} = sendObj
Ajax.onreadystatechange = function (){
if(this.readyState === 4){
complete && complete();
}
if(this.readyState === 4 && this.status === 200){
try {
success && success(JSON.parse(Ajax.responseText));
}catch (err){
success && success(Ajax.responseText);
}
}else{
fail && fail();
}
};
Ajax.open(type,baseUrl+api,true);
let sendData = data
if(dataType !== 'formData'){
Ajax.setRequestHeader('Content-Type', 'application/json');
sendData = JSON.stringify(data)
}
headers && setHeader(headers)
Ajax.setRequestHeader('token', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOjEsImlhdCI6MTYzNjM1Nzg1NCwiZXhwIjoxODA5MTU3ODU0fQ.Kw0DZcOhFqerNtP8Z9ohj_1Py-2MHtQwC6P6odVDgmw');
Ajax.send(sendData);
function setHeader(headers){
for (const headersKey in headers) {
if(headers.hasOwnProperty(headersKey)){
Ajax.setRequestHeader(headersKey, headers[headersKey]);
}
}
}
}
使用/以及过程
ajax({
type: "post",
api: "/api/public/upload",
data: formData,
// 用来区分文件上传与否了,其他情况我都写死了为json格式
dataType: "formData",
// 可以使用headers对其进行重写
headers:{'token':'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOjEsImlhdCI6MTYzNjM1Nzg1NCwiZXhwIjoxODA5MTU3ODU0fQ.Kw0DZcOhFqerNtP8Z9ohj_1Py-2MHtQwC6P6odVDgmw'},
success: function (res) {
let img = document.createElement('img')
img.setAttribute('src',res.data.url)
document.body.append(img)
}
});
文件上传前端
文件上传
不管是单文件上传,还是多文件上传。 前端就是控制 input框上的multiple属性就好。
<input type="file" multiple id="file"/>
上传的时候时候需要指定上传为表单类型。可以通过 FromData对象添加。 部分浏览器步支持这个属性,可以通过from表单提交,先看FromData方式的。
let file = document.getElementById('file');
let formData = new FormData();
for (let i = 0; i < file.files.length; i++) {
formData.append("file", file.files[i]);
}
ajax({
type: "post",
api: "/api/public/upload",
data: formData,
headers:{'token':'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOjEsImlhdCI6MTYzNjM1Nzg1NCwiZXhwIjoxODA5MTU3ODU0fQ.Kw0DZcOhFqerNtP8Z9ohj_1Py-2MHtQwC6P6odVDgmw'},
dataType: "formData",
success: function (res) {
let img = document.createElement('img')
img.setAttribute('src',res.data.url)
document.body.append(img)
}
});
文件上传node koa2
node上传我们使用插件 koa-multer
定义存储位置。
const multer = require('koa-multer');
const storage = multer.diskStorage({
destination: async function (req, file, cb) {
cb(null, 'tmp/');
},
filename: function (req, file, cb) {
const fileFormat = (file.originalname).split(".");
cb(null, Date.now() + "." + fileFormat[fileFormat.length - 1]);
}
});
const upload = multer({storage});
在node路由使用
router.post('/upload', upload.fields([
{
name: 'file',
maxCount: 1
},
{
name: 'imgs',
maxCount: 4
}
]), async (ctx) => {
console.log(ctx.req.files)
});
在这个路由中,我么可以通过ctx.req.files拿到一个对象。
这个对象中是可以拿到,上面定义的imgs 和 file两个对象的 都是数组。
至此 简单的ajax封装到简单的文件上传,就已经完成。