宝哥软件园

Ajax异步文件上传和NodeJS快速服务器处理

编辑:宝哥软件园 来源:互联网 时间:2021-09-05

为了避免在实现简单的异步文件上传功能时引入第三方库文件的尴尬情况(库文件可能会造成冗余开销,降低应用加载速度,尤其是引入库文件后只用到一两个功能时,性价比极低),我最近了解了一下异步文件上传的实现原理,顺便看了一下进度条、图片预览等功能的实现,做了一些简单的安排。

文件上传

HTML结构如下,一个文件输入和一个按钮。当点击“上传”按钮时,将通过文件输入选择的文件上传到服务器。

输入类型='文件'名称='文件' id='文件'/按钮id='上传'上传/按钮以下是“上传”按钮的点击事件处理程序。单击按钮后,XMLHttpRequest对象用于发送异步请求。上传的内容是文件,所以需要FormData对象。FormData可以在js中创建一个表单对象,将文件输入的文件追加到FormData对象中,最后调用XHR对象的send()方法将表单数据发送出去。

var file=document . queryselector(' # file ');var upload=document . queryselector(' # upload ');var xhr=new XMLHttpRequest();//点击上传功能上传文件(事件){ var formdata=new formdata();formData.append('test-upload ',file . files[0]);xhr.onload=uploadSuccessxhr.open('post ','/upload ',true);xhr . send(formData);}//成功上传函数上传成功(事件){if (xhr。ready state===4){ console . log(xhr。response text);}}上传进度

上传文件时,xhr对象将有一个上传属性,它将提供一个进度事件。在相应的事件处理程序中,可以通过事件对象知道当前的上传进度。使用此功能,您可以轻松实现进度条或进度提示。

输入类型=' file ' name=' file ' id=' file '/button id=' upload ' upload/button span id=' progress ' 0%/span var progress=document . queryselector(' progress ');//点击上传功能上传文件(事件){ varformdata=new formdata();formData.append('test-upload ',file . files[0]);xhr.onload=uploadSuccessxhr . upload . on progress=SetProgress;xhr.open('post ','/upload ',true);xhr . send(formData);}//进度条函数设置进度(event){ if(event . length complete){ var complete=number . parsent(event.loaded/event.total * 100);progress . innerhtml=complete“%”;}}图片预览

FileReader对象可用于上传图片时预览图片。文件阅读器可以异步读取用户计算机上的文件,并将文件输入选择的文件发送给文件阅读器。读取后,可以获取文件的网址,并设置为图像元素的src,从而可以显示选定的图像文件。

输入类型=' file ' name=' file ' id=' file '/button id=' upload ' upload/button span id=' progress ' 0/span img id=' image ' src=' http : ' width=' 200 '/var file=document . queryselector(' #)file . addeventlistener(' change ',previewImage,false);//图片预览功能预览图像(事件){ varreader=new file reader();reader . onload=function(event){ image . src=event . target . result;};reader . readasdataurl(event . target . files[0]);}服务器端处理

使用express构建一个简单的NodeJS服务器,它提供了一个上传文件的接口。Express需要中间件支持文件上传。快递官网上有很多介绍。这里我使用了multer中间件,这里有一个简单的例子。Upload.single表示此接口接受的上传文件数为1,“test-upload”将上传表单数据的关键字限制为“test-upload”(formdata . append(‘test-upload’,file . files[0]);)。该中间件处理后,可以通过req.file访问文件的相关信息,上传的文件存储在上传文件夹中。

const upload=require(' multer ')({ dest : ' uploads/' });app.post('/upload ',upload.single('test-upload '),(req,res)={ //没有附带文件if(!请求。文件){ RES . JSON({ ok : false });返回;} //输出文件信息控制台。日志('===============================================================');控制台。日志('字段名: '请求。文件。字段名称);控制台。日志('原始名称: '请求。文件。原名称);控制台。日志('编码: '请求。文件。编码);控制台。日志(' mime类型: '请求。文件。mime类型);控制台。日志('大小: '(请求。文件。尺寸/1024 ).toFixed(2)“KB”);控制台。日志('目标: '请求。文件。目的地);控制台。日志(' filename : '请求。文件。文件名);控制台。日志('路径: '请求。文件。路径);});

由输出可以看到,文件的命名使用一个哈希值表示,并且去除了后缀名,想要保持文件的原有的命名格式,需要再通过满量程对文件进行改名。

app.post('/upload ',upload.single('test-upload '),(req,res)={ //没有附带文件if(!请求。文件){ RES . JSON({ ok : false });返回;} //输出文件信息控制台。日志('===============================================================');控制台。日志('字段名: '请求。文件。字段名称);控制台。日志('原始名称: '请求。文件。原名称);控制台。日志('编码: '请求。文件。编码);控制台。日志(' mime类型: '请求。文件。mime类型);控制台。日志('大小: '(请求。文件。尺寸/1024 ).toFixed(2)“KB”);控制台。日志('目标: '请求。文件。目的地);控制台。日志(' filename : '请求。文件。文件名);控制台。日志('路径: '请求。文件。路径);//重命名文件让旧路径=路径。join(_ dirname,req。文件。路径);让new PATH=path . join(_ dirname,' uploads/'请求。文件。原名称);fs.rename(oldPath,newPath,(err)={ if(err){ RES . JSON({ ok : false });控制台。日志(err);} else { RES . JSON({ ok : true });} });});完整代码

创建交互式、快速动态网页应用的网页开发技术异步文件上传、进度显示、图片预览

输入类型='文件'名称='文件id='文件'/按钮id='上传'上传/button span id=' progress ' 0/span mg id=' image ' src=' http : ' width=' 200 '/(function(){ ' use strict ';var文件=文档。query selector(' # file ');var上传=文档。query selector(' # upload ');var progress=文档。查询选择器(' # progress ');var image=文档。查询选择或(' # image ');var xhr=new XMLHttpRequest();upload.addEventListener('click ',uploadFile,false);file.addEventListener('change ',previewImage,false);//点击上传函数uploadFile(事件){ var formData=new formData();formData.append('test-upload ',文件。文件[0]);xhr.onload=uploadSuccessxhr。上传。进行中=设定程序;xhr.open('post ','/upload ',true);xhr。发送(表单数据);} //成功上传函数上传成功(事件){ if(xhr。readystate===4){ console。日志(xhr。response text);} } //进度条函数设定程序(事件){ if(事件。长度可计算){ var complete=number。parsent(事件。已加载/事件。合计* 100);进步。innerhtml=完整的“%”;} } //图片预览函数预览图像(事件){ var reader=new file reader();读者。onload=function(event){ image。src=事件。目标。结果;};读者。readasdataurl(事件。目标。文件[0]);}})();表达服务器提供文件上传接口

const express=require(' express ');const upload=require(' multer ')({ dest : ' uploads/' });const path=require(' path ');const fs=require(' fs ');const port=8080 let app=express();app.set('端口,港口);//index.html放在静电文件夹中app。使用(快递。静态(路径。join(_ _ dirname,' static '));app.get('* ',(req,RES)={ RES . redirect(' index。html ');});app.post('/upload ',upload.single('test-upload '),(req,res)={ //没有附带文件if(!请求。文件){ RES . JSON({ ok : false });返回;} //输出文件信息控制台。日志('===============================================================');控制台。日志('字段名: '请求。文件。字段名称);控制台。日志('原始名称: '请求。文件。原名称);控制台。日志('编码: '请求。文件。编码);控制台。日志(' mime类型: '请求。文件。mime类型);控制台。日志('大小: '(请求。文件。尺寸/1024 ).toFixed(2)“KB”);控制台。日志('目标: '请求。文件。目的地);控制台。日志(' filename : '请求。文件。文件名);控制台。日志('路径: '请求。文件。路径);//重命名文件让旧路径=路径。join(_ dirname,req。文件。路径);让new PATH=path . join(_ dirname,' uploads/'请求。文件。原名称);fs.rename(oldPath,newPath,(err)={ if(err){ RES . JSON({ ok : false });控制台。日志(err);} else { RES . JSON({ ok : true });} });});app.listen(端口,()={控制台。日志('[服务器] localhost: '端口);});以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持我们!

更多资讯
游戏推荐
更多+