自己做的手工在哪个网站卖会更好,html5简单网页大作业,产品设计一般出多少方案,wordpress采集电影资源利用 FormData 实现文件上传
基础功能#xff1a;上传文件
演示如下#xff1a; 概括流程#xff1a; 前端#xff1a;把文件数据获取并 append 到 FormData 对象中后端#xff1a;通过 ctx.request.files 对象拿到二进制数据#xff0c;获得 node 暂存的文件路径 前端…利用 FormData 实现文件上传
基础功能上传文件
演示如下 概括流程 前端把文件数据获取并 append 到 FormData 对象中后端通过 ctx.request.files 对象拿到二进制数据获得 node 暂存的文件路径 前端
前端的工作就是把页面写好ajax 和 FormData 组装好发送给后端。
基础功能组装 FormData 和 XHR
前端这边代码如下
!DOCTYPE html
html langenheadmeta charsetUTF-8 /meta nameviewport contentwidthdevice-width, initial-scale1.0 /titleDocument/title/headbodyinput typefile namefile idfile /button idbtn点我上传/button/bodyscriptconst btn document.getElementById(btn);btn.onclick function () {let file document.querySelector(#file).files[0];console.log(file);// 组装好 formData// 文件传输是通过正文传输的所以要用 postlet formData new FormData(); // 这里的 new formData() 会自动帮我设置 content-typeformData.append(data, file);formData.append(name, 文件);formData.append(年龄, 20);// 组装好 xhrlet xhr new XMLHttpRequest();xhr.open(post, /upload);xhr.onload function () {console.log(xhr.responseText);};xhr.send(formData);};/script
/html基础xhr.upload 上传钩子函数
大概有如下几个钩子比较常用的
xhr.upload.onprogress (event) {console.log(上传过程);
}
xhr.upload.onload () {console.log(上传成功);
}
xhr.upload.onloadend () {console.log(上传完成);
}
xhr.upload.onabort () {console.log(取消上传);
}onprogress 这个函数是在上传过程中不断循环被执行的其中有事件因子 event里面会有上传中的信息
如果想要监控速度和进度的话可以在上传的过程中计算出来
如果想要取消上传就把 xhr.abort() 即可。
document.getElementById(cancelBtn).addEventListener(click, function () {// 取消上传xhr.abort();
});
基础利用钩子函数计算下载速度和进度 速度思路就是求出一段时间的下载量(byte)和一段时间(s)然后做除法 s p e e d d 单位数据包大小 b y t e d 单位时间 s b y t e / s speed \frac{{\rm d}单位数据包大小 byte}{{\rm d }单位时间 s}{byte/s} speedd单位时间sd单位数据包大小bytebyte/s let oldDataSize;
let oldTime;
xhr.onload function () {let responseText xhr.responseText;console.log(上传成功, responseText);
};
xhr.upload.onloadstart () {console.log(上传开始);oldLoaded 0;oldTime new Date().getTime();
};
xhr.upload.onprogress (enent) {// 计算单位时间文件加载大小let duringLoaded event.loaded - oldLoaded;// 计算单位时间差let duringTime (new Date().getTime() - oldTime) / 1000; // 时间戳默认单位是毫秒// 记录旧的数据下次循环的时候需要用的oldTime new Date().getTime();oldLoaded event.loaded;console.log(上传中:, event);
};进度已经上传的数据loaded 与总数据 total 的比值 p r o g r e s s 已上传数据包大小 b y t e 总文件大小 b y t e ∗ 100 % progress \frac{已上传数据包大小 byte}{总文件大小 byte} { * } {100}{\%} progress总文件大小byte已上传数据包大小byte∗100% 完善添加进度条以及速度标识
整体代码如下
!DOCTYPE html
html langenheadmeta charsetUTF-8 /meta nameviewport contentwidthdevice-width, initial-scale1.0 /titleDocument/title/headbodyinput typefile namefile idfile /div进度 progress value0 max100 idprogress/progress/divdiv速度 span idspeed/span span idunit/span/divbutton idbtn上传/buttonbutton idcancelBtn取消上传/button/bodyscriptconst btn document.getElementById(btn);let xhr new XMLHttpRequest();let oldDataSize;let oldTime;btn.onclick function () {let file document.querySelector(#file).files[0];console.log(file);// 组装好 formData// 文件传输是通过正文传输的所以要用 postlet formData new FormData(); // 这里的 new formData() 会自动帮我设置 content-typeformData.append(data, file);formData.append(name, 文件);formData.append(年龄, 20);// 组装好 xhrxhr.open(post, /upload);xhr.onload function () {console.log(xhr.responseText);};xhr.upload.onloadstart (event) {console.log(开始上传);oldLoaded 0;oldTime new Date();};// onprogress 钩子函数会不停地被调用xhr.upload.onprogress (event) {console.log(正在上传:, event);// 计算速度let duringLoaded (event.loaded - oldLoaded) / 1024;let duringTime (new Date() - oldTime) / 1000; // 时间戳默认单位是毫秒// 记录旧的数据下次循环的时候需要用的oldTime new Date();oldLoaded event.loaded;let speed duringLoaded / duringTime; // 单位是 bt/slet unit b/s;if (speed 1024) {speed speed / 1024;unit kb/s;}if (speed 1024) {speed speed / 1024;unit mb/s;}if (speed 1024) {speed speed / 1024;unit gb/s;}if (speed 1024) {speed speed / 1024;unit tb/s;}document.getElementById(speed).innerHTML ${speed};document.getElementById(unit).innerHTML ${unit};// 计算进度const { total, loaded } event;let progress ((loaded / total) * 100).toFixed(0);document.getElementById(progress).value progress;};xhr.upload.onload () {console.log(上传成功);};xhr.upload.onloadend () {console.log(上传完成);};xhr.upload.onabort () {console.log(取消上传);};xhr.send(formData);};document.getElementById(cancelBtn).addEventListener(click, function () {// 取消上传xhr.abort();});/script
/html后端
后端获取相应数据的方式如下
router.post(/upload, ctx {console.log(ctx.request.body); // 接收文字console.log(ctx.request.files); // 接收文件信息
})node 会帮我们把二进制文件存储到临时地址我们可以通过 fs 模块拿到文件然后写到自己想要的位置 基本功能拿到二进制数据并转存文件
后端接收注意要在 KoaBody 这里允许上传文件具体的知识点可以阅读一下这篇博文理解 HTTP 中的 multipart/form-data
app.use(KoaBody({multipart: true
}))后端代码如下
const Koa require(koa);
const View require(koa-views);
const Router require(koa-router);
const { koaBody } require(koa-body);
const Static require(koa-static);
const fs require(fs);
const app new Koa();
const router new Router();
app.use(View(__dirname));
app.use(Static(__dirname));
app.use(koaBody({ multipart: true }));
// 异步函数
router.get(/, async (ctx, next) {await ctx.render(index.html);
});// 异步函数
router.post(/upload, async (ctx, next) {console.log(ctx.request.files:, ctx.request.files);console.log(ctx.request.body:, ctx.request.body);const filePath ctx.request.files.data.filepath;const readFile fs.readFileSync(filePath);fs.writeFileSync(static/ ctx.request.files.data.originalFilename, readFile);ctx.body 请求成功;
});app.use(router.routes());
app.listen(3000, () {console.log(server start:, http://localhost:3000);
});优化文件夹的判断以及错误处理
可以检测文件夹是否存在如果文件夹不存在的话自然会报错完善后的代码如下
/*** 说明* fs.exists() 已弃用但 fs.existsSync() 不是。* fs.exists() 的 callback 参数接受与其他 Node.js 回调不一致的参数。 fs.existsSync() 不使用回调* 参考地址https://nodejs.cn/api/fs/fs_existssync_path.html*/
router.post(/upload, async (ctx, next) {try {// console.log(ctx.request.files:, ctx.request.files);// console.log(ctx.request.body:, ctx.request.body);const data ctx.request.files.data;const { filepath, originalFilename } data;if (!fs.existsSync(static)) {fs.mkdirSync(static);}const readFile fs.readFileSync(filepath);fs.writeFileSync(static/${originalFilename}, readFile);ctx.body 请求成功;} catch (err) {console.log(err);}
});断点续传
Q A
Error: options.maxFileSize (209715200 bytes) exceeded, received 209731427 bytes of file data 这是后端有上传文件大小限制的问题在 koa-body 配置中把文件改的大一些默认是 200mb点我查看源文档 /*** 设置上传文件大小最大限制默认1000M* https://github.com/node-formidable/formidable*/
app.use(koaBody({multipart: true,formidable: {maxFileSize: 1000 * 1024 * 1024, },})
);