node_上传文件multer+上传文件Ajax+文件下载
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了node_上传文件multer+上传文件Ajax+文件下载,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含15736字,纯文字阅读大概需要23分钟。
内容图文
![node_上传文件multer+上传文件Ajax+文件下载](/upload/InfoBanner/zyjiaocheng/609/f01e9c803054444c9418bcb3b8006620.jpg)
非原创
本文转自https://github.com/a415432669/-front_end_notebook/tree/master/Node/day6/%E6%96%87%E6%A1%A3
一、multer中间件
再上传文件时,我们通常会使用到他。Multer用于处理multipart/form-data 类型的表单数据。首先我们先安装它:
cnpm install multer --save
二、使用
首先在form表单中我们需要设置enctype为:multipart/form-data表单类型。同时我们也需要用到fs模块对文件重命名。下面是单文件上传实例:
<!DOCTYPE html>
<html>
?? ?<head>
?? ??? ?<meta charset="utf-8">
?? ??? ?<title></title>
?? ?</head>
?? ?<body>
?? ??? ?<form action="http://localhost:8080/" method="post" enctype="multipart/form-data">
?? ??? ??? ?<input type="file" name="files" value="指定文件">
?? ??? ??? ?<br><br>
?? ??? ??? ?<input type="submit" value="上传">
?? ??? ?</form>
?? ?</body>
</html>
const express=require("express");
const multer=require('multer');
//初始化上传对象
var upload=multer({dest:'./upload/'});
var fs = require('fs');
var app=express();
app.use("/",upload.single("files"),function(req,res){?? ?//files为input type="file"的name值
?? ?var oldFile=req.file.destination+req.file.filename;?? ?//指定旧文件
?? ?var newFile=req.file.destination + req.file.originalname;?? ?//指定新文件
?? ?fs.rename(oldFile,newFile,function(err){
?? ??? ?if(err){
?? ??? ??? ?res.send('上传失败!');
?? ??? ?}else{
?? ??? ??? ?res.send('上传成功!');
?? ??? ?}
?? ?});
});
app.listen(8080);
在这里我们可以指定单个文件上传到根目录的upload文件夹里。这里值得注意的是req.file会返回文件的基本信息:
fieldname: ***, //input type="file"的name值
originalname: ***, //用户计算机上的文件的名称
encoding: '***', //文件编码
mimetype: ***', //文件的 MIME 类型
destination: './***/', //保存路径
filename: ***, //保存在 destination 中的文件名
path: ***, //已上传文件的完整路径
size: ** //文件大小(字节单位)
三、上传多个文件
在HTML找中input type="file"需要加上multiple来实现过滤,multiple不写参数则可以读取·所有文件。而在服务端上,我们需要将single()改为array(“name”,num);的形式来接收多个文件的上传请求。最后对他们全部进行重命名。在这之前我们首先看看multer支持哪些文件上传方式:
.single(fieldname) //接受一个以 fieldname 命名的文件。.fields(fields)
.array(fieldname[, maxCount]) //接受一个以 fieldname 命名的文件数组。可以配置 maxCount 来限制上传的最大数量。
.fields(fields) //接受指定 fields 的混合文件。fields是一个拥有name和maxCount的数组对象。
.none() //只接受文本域。如果任何文件上传到这个模式,将发生 "LIMIT_UNEXPECTED_FILE" 错误。
.any() //接受一切上传的文件。
下面我们将会演示如何上传多个文件:
<!DOCTYPE html>
<html>
?? ?<head>
?? ??? ?<meta charset="utf-8">
?? ??? ?<title></title>
?? ?</head>
?? ?<body>
?? ??? ?<form action="http://localhost:8080/" method="post" enctype="multipart/form-data">
?? ??? ??? ?<input type="file" name="files" value="指定文件" multiple>
?? ??? ??? ?<br><br>
?? ??? ??? ?<input type="submit" value="上传">
?? ??? ?</form>
?? ?</body>
</html>
const express=require("express");
const multer=require('multer');
var upload=multer({dest:'./upload/'});
var fs = require('fs');
var app=express();
app.use("/",upload.array("files",5),function(req,res,next){
?? ?req.files.forEach(function(ele,index){
?? ??? ?console.log(ele);
?? ??? ?var oldFile=ele.destination+ele.filename;?? ?//指定旧文件
?? ??? ?var newFile=ele.destination+ele.originalname;?? ?//指定新文件
?? ??? ?fs.rename(oldFile,newFile,function(err){
?? ??? ??? ?err?console.log('上传失败!'):console.log('上传成功!');
?? ??? ?});
?? ?});
?? ?res.send("成功上传");
});
app.listen(8080);
这里,我们获取文件信息是通过req.files来获取,他是由数组构成的对象,之后用foreach循环对其进行重命名即可。
四、通过limits来限制上传文件
Multer通过使用limits这个对象来对数据进行限制,它允许使用以下参数:
Key Description Default
fieldNameSize field 名字最大长度 100 bytes
fieldSize field 值的最大长度 1MB
fields 非文件 field 的最大数量 无限
fileSize 在 multipart 表单中,文件最大长度 (字节单位) 无限
files 在 multipart 表单中,文件最大数量 无限
parts 在 multipart 表单中,part 传输的最大数量(fields + files) 无限
headerPairs 在 multipart 表单中,键值对最大组数 2000
如果你上传的文件超出这些设定,MulterError模块将会启用,该模块在node_modules/multer/lib/multer-error.js上:
我们可以使用err.code定位到该错误,他有7种code方式,不同设置会返回不同code;
LIMIT_PART_COUNT
LIMIT_FILE_SIZE
LIMIT_FILE_COUNT
LIMIT_FIELD_KEY
LIMIT_FIELD_VALUE
LIMIT_FIELD_COUNT
LIMIT_FIELD_COUNT
下面就给大家做个简单实例:
html依然不变,js代码如下:
var upload=multer({dest:'./upload/',limits:{fileSize: 1024 * 1024 * 20,files: 5}});
fileSize: 1024 * 1024 * 20,设置的大小为20m;files限制上传的数量;
const express=require("express");
const multer=require('multer');
var upload=multer({dest:'./upload/',limits:{fileSize: 1024 * 1024 * 20,files: 5}});
var fs = require('fs');
var app=express();
app.use("/",upload.array("files",5),function(req,res,next){
?? ?req.files.forEach(function(ele,index){
?? ??? ?var oldFile=ele.destination+ele.filename;?? ?//指定旧文件
?? ??? ?var newFile=ele.destination+ele.originalname;?? ?//指定新文件
?? ??? ?fs.rename(oldFile,newFile,function(err){
?? ??? ??? ?err?console.log('上传失败!'):console.log('上传成功!');
?? ??? ?});
?? ?});
?? ?next();
?? ?res.send("上传成功!");
});
app.use(function(err,req,res,next){
?? ?if (err.code==='LIMIT_FILE_SIZE'){
?? ??? ?res.send('File is too large');
?? ?}else if(err.code==='LIMIT_FILE_COUNT'){
?? ??? ?res.send('Too many files');
?? ?}
})
app.listen(8080);
图片处理:用开源图像处理软件Open...;node间接让c跑图片处理插件,node处理图像性能很差,必须调用插件
app.js
var cookieParser = require('cookie-parser');
let session = require('express-session');
let uploadRouter = require('./routes/uploadRouter');
app.use('/imgUpload', uploadRouter);
uploadRouter.js
var express = require('express');
var router = express.Router();
// 引入上传模块
let multer = require('multer');
// 配置上传对象
let upload = multer({
dest: "./public/upload"
});
var fs = require('fs');
/* GET users listing. */
router.get('/', function (req, res, next) {
res.render('uploadimg.ejs');
});
// 处理上传的post请求
// 如果上传单个文件,可调用upload.single('imgfile')方法,并且将表单文件的name值传入
router.post('/', upload.single('imgfile'), function (req, res) {
console.log(req.file);
// 因为直接上传的文件为随机名字,我们想要重新命名
let oldPath = req.file.destination + "/" + req.file.filename;
let newPath = req.file.destination + "/" + req.file.filename + req.file.originalname;
fs.rename(oldPath, newPath, () => {
console.log("改名成功");
})
res.send("<h1>上传成功</h1><img src='/upload/" + req.file.filename + req.file.originalname + "'/>");
})
module.exports = router;
uploadimg.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>图片上传</h1>
<!-- 表单上传文件时,需改变属性enctype为enctype="multipart/form-data",即定义表单的上传类型为文件类型 -->
<form action="/imgUpload" method="POST" enctype="multipart/form-data">
<input type="file" name="imgfile">
<button type="submit">上传</button>
</form>
</body>
</html>
AJAX上传图片
图片上传实现步骤
图片上传
通过jquery监听input change事件,这样我们可以获取到上传的图片流信息,从而可以获取到图片的地址、大小、格式以及名称等信息
这里创建3个数组,imgName、imgSrc、imgFile分别用于存放上传图片的名称、url地址以及图片流信息
var fileList = this.files;
? ? ? ? for(var i = 0; i < fileList.length; i++) {
? ? ? ? ? ? var imgSrcI = getObjectURL(fileList[i]);
? ? ? ? ? ? imgName.push(fileList[i].name);
? ? ? ? ? ? imgSrc.push(imgSrcI);
? ? ? ? ? ? imgFile.push(fileList[i]);
? ? ? ? }
getObjectURL方法是一个用于获取本地图片的地址,使用该url可以显示图片
function getObjectURL(file) {
? ? var url = null ;
? ? if (window.createObjectURL!=undefined) { // basic
? ? ? ? url = window.createObjectURL(file) ;
? ? } else if (window.URL!=undefined) { // mozilla(firefox)
? ? ? ? url = window.URL.createObjectURL(file) ;
? ? } else if (window.webkitURL!=undefined) { // webkit or chrome
? ? ? ? url = window.webkitURL.createObjectURL(file) ;
? ? }
? ? return url ;
}
控制上传图片大小、格式以及上传数量
$('#upload').on('change',function(){ ? ? ? ?
? ? ? ? ? if(imgSrc.length==4){
? ? ? ? ? ? return alert("最多只能上传4张图片");
? ? ? ? }
? ? ? ? var imgSize = this.files[0].size; ?//b
? ? ? ? if(imgSize>1024*1024*1){//1M
? ? ? ? ? ? return alert("上传图片不能超过1M");
? ? ? ? }
? ? ? ? if(this.files[0].type != 'image/png' && this.files[0].type != 'image/jpeg' && this.files[0].type != 'image/gif'){
? ? ? ? ? ? return alert("图片上传格式不正确");
? ? ? ? }
? ? })
图片预览
创建一个addNewContent方法用于动态展示添加的图片实现图片预览,在每次上传图片的时候调用该方法
function addNewContent(obj) {
? ? $(obj).html("");
? ? for(var a = 0; a < imgSrc.length; a++) {
? ? ? ? var oldBox = $(obj).html();
? ? ? ? $(obj).html(oldBox + '<li class="content-img-list-item"><img src="'+imgSrc[a]+'" alt=""><a index="'+a+'" class="hide delete-btn"><i class="ico-delete"></i></a></li>');
? ? }
}
图片删除
1.通过监听鼠标的mouseover事件,显示图片删除按钮
$('.content-img-list').on('mouseover','.content-img-list-item',function(){
$(this).children('a').removeClass('hide');
});
2.监听鼠标的mouseleave事件,隐藏图片删除按钮
$('.content-img-list').on('mouseleave','.content-img-list-item',function(){
$(this).children('a').addClass('hide');
});
3.获取图片index下标属性,通过js的splice方法删除数组元素,重新调用addNewContent方法遍历图片数组显示预览图片
$(".content-img-list").on("click",'.content-img-list-item a',function(){
? ? ? ? ? ? var index = $(this).attr("index");
? ? ? ? ? ? imgSrc.splice(index, 1);
? ? ? ? ? ? imgFile.splice(index, 1);
? ? ? ? ? ? imgName.splice(index, 1);
? ? ? ? ? ? var boxId = ".content-img-list";
? ? ? ? ? ? addNewContent(boxId);
? ? ? ? ? ? if(imgSrc.length<4){//显示上传按钮
? ? ? ? ? ? ? ? $('.content-img .file').show();
? ? ? ? ? ? }
? ? ? });
图片上传提交
这里主要使用FormData来拼装好数据参数,提交到后台
var formFile = new FormData();
遍历imgFile图片流数组拼装到FormData中
$.each(imgFile, function(i, file){
formFile.append('myFile[]', file);
});
添加其他参数
formFile.append("type", type);
formFile.append("content", content);
formFile.append("mobile", mobile);
最后使用ajax提交内容
?$.ajax({
? ? ? ? ? ? url: 'http://zhangykwww.yind123.com/webapi/feedback',
? ? ? ? ? ? type: 'POST',
? ? ? ? ? ? data: formFile,
? ? ? ? ? ? async: true, ?
? ? ? ? ? ? cache: false, ?
? ? ? ? ? ? contentType: false,?
? ? ? ? ? ? processData: false,?
? ? ? ? ? ? // traditional:true,
? ? ? ? ? ? dataType:'json',
? ? ? ? ? ? success: function(res) {
? ? ? ? ? ? ? ? console.log(res);
? ? ? ? ? ? }
? ? ? ? })
以上就实现了图片上传、图片预览和图片删除的功能
jquery设置 ajax属性
processData : false, // 告诉jQuery不要去处理发送的数据
contentType : false,// 告诉jQuery不要去设置Content-Type请求头
整体代码:
uploadRouter.js
var express = require('express');
var router = express.Router();
// 引入上传模块
let multer = require('multer');
// 配置上传对象
let upload = multer({
dest: "./public/upload"
});
var fs = require('fs');
/* GET users listing. */
router.get('/', function (req, res, next) {
res.render('uploadimg.ejs');
});
// 处理上传的post请求
// 如果上传单个文件,可调用upload.single('imgfile')方法,并且将表单文件的name值传入
// router.post('/', upload.single('imgfile'), function (req, res) {
// console.log(req.file);
// // 因为直接上传的文件为随机名字,我们想要重新命名
// let oldPath = req.file.destination + "/" + req.file.filename;
// let newPath = req.file.destination + "/" + req.file.filename + req.file.originalname;
// fs.rename(oldPath, newPath, () => {
// console.log("改名成功");
// })
// res.send("<h1>上传成功</h1><img src='/upload/" + req.file.filename + req.file.originalname + "'/>");
// })
router.post('/', upload.single('imgfile'), function (req, res) {
console.log(req.file);
// 因为直接上传的文件为随机名字,我们想要重新命名
let oldPath = req.file.destination + "/" + req.file.filename;
let newPath = req.file.destination + "/" + req.file.filename + req.file.originalname;
fs.rename(oldPath, newPath, () => {
console.log("改名成功");
})
// ajax传过去应该是json字符串
res.json({
state: 'ok',
imgUrl: "/upload/" + req.file.filename + req.file.originalname
})
})
router.get('/ajax', (req, res) => {
res.render('uploadajax');
})
module.exports = router;
uploadAjax.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>图片上传</h1>
<!-- 表单上传文件时,需改变属性enctype为enctype="multipart/form-data",即定义表单的上传类型为文件类型 -->
<form id="uploadForm" action="/imgUpload" method="POST" enctype="multipart/form-data">
<label for="imgInput">选择文件</label>
<input hidden id="imgInput" type="file" name="imgfile">
<div class="btn">上传</div>
</form>
<div>
<h3>预览</h3>
<img id="imgLook" src="" alt="">
</div>
<script src='/javascripts/jquery.min.js'></script>
<script>
let formDataObj = new FormData();
let file;
$('#imgInput').change(function (e) {
// console.log($('#uploadForm'));
console.log(this.files);
// 图片预览就是把this.files[0]变成地址之类,别人通过访问你的地址显示这个图
file = this.files[0];
// 创建预览图片地址
let httpUrl = window.webkitURL.createObjectURL(file);
$('#imgLook').attr("src", httpUrl);
// 创建formData对象,将文件追加到formData对象里
// 因为之前uploaadRouter中写的是upload.single('imgfile');所以每次上传一个,而想上传多个,这里就需要每次都会new一次
formDataObj = new FormData();
formDataObj.append("imgfile", file);
})
$('.btn').click(function () {
$.ajax({
url: "/imgUpload",
method: "POST",
data: formDataObj,
processData: false, //不需要处理数据
contentType: false, //不需要设置类型
}).then(function (res) {
console.log(res);
$('body').append(`<h1>上传成功</h1><img src='${res.imgUrl}'>`);
})
})
</script>
</body>
</html>
文件下载
文件下载非常简单,仅需通过res.download()执行即可,他可以写为3种形式:
res.download('/report-12345.pdf');
以下是一个对选择对应文件进行下载的实例:
html:
<!DOCTYPE html>
<html>
?? ?<head>
?? ??? ?<meta charset="utf-8">
?? ??? ?<title></title>
?? ?</head>
?? ?<body>
?? ??? ?<form action="http://localhost:8080/" method="post" enctype="application/x-www-form-urlencoded">
?? ??? ??? ?<input type="file" name="files" value="选择下载的文件"><br><br>
?? ??? ??? ?<input type="submit" value="下载">
?? ??? ?</form>
?? ?</body>
</html>
js:
const express=require("express");
const bodyParser=require("body-parser");
var app=express();
var jsonParser = bodyParser.json();
var urlencodedParser = bodyParser.urlencoded({ extended: false });
app.post('/',urlencodedParser,function(req,res){
?? ?res.download("./public/"+req.body.files,err=>{
?? ??? ?if(err){
?? ??? ??? ?res.send("下载失败!");
?? ??? ?}else{
?? ??? ??? ?console.log("下载成功!");
?? ??? ?}
?? ?});
});
app.listen(8080);
我们可以选择根目录public下的文件对其进行下载。
整体代码:
app.js
let downloadRouter = require('./routes/downloadRouter');
app.use('/download', downloadRouter);
downloadRouter.js
var express = require('express');
var router = express.Router();
var sqlQuery = require("../lcMysql");
/* GET home page. */
router.get('/dl/:bookid', async function (req, res, next) {
let bookid = req.params.bookid;
// 通过bookid查询数据库,获取本地的文件下载路径
let sqlStr = 'select localdownload from book where id=?';
let result = await sqlQuery(sqlStr, [bookid]);
let localPath = result[0].localdownload;
res.download(localPath);
});
module.exports = router;
bookInfo.ejs
<div class="localdownload"><a href="/download/dl/10">本地下载</a></div>
<style>
.localdownload {
background: skyblue;
text-align: center;
margin-bottom: 200px;
height: 80px;
line-height: 80px;
}
.localdownload a {
color: #fff;
text-decoration: none;
}
</style>
内容总结
以上是互联网集市为您收集整理的node_上传文件multer+上传文件Ajax+文件下载全部内容,希望文章能够帮你解决node_上传文件multer+上传文件Ajax+文件下载所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。