nodejs图片上传
nodejs一般开发网站基本都用express框架,本文也主要以express为例,讲解如何上传图片;
express本身没有上传图片功能;一般都是集成相应的模块;常用的有multer中间件和formidable中间件,前一个我配置的时候总是出错,所以pass;此处主要演示formidable的用法;
首先前端页面配置,无非两种,
-表单提交;
-ajax提交;
表单提交代码如下:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<form action="/uploader" method="post" enctype="multipart/form-data">
<!--注意此处的name和后端files的属性对应-->
<input type="file" name="fulAvatar">
<input type="submit">
</form>
</body>
</html>
这里注意表单的enctype属性一定要是:multipart/form-data
;<input type="file" name="fulAvatar">
别忘了name属性;
这是html文档的讲解:
定义和用法
enctype 属性规定在发送到服务器之前应该如何对表单数据进行编码。
默认地,表单数据会编码为 "application/x-www-form-urlencoded"。就是说,在发送到服务器之前,所有字符都会进行编码(空格转换为 "+" 加号,特殊符号转换为 ASCII HEX 值)。
ajax提交:
<!DOCTYPE>
<html>
<head>
<title> formdata file jquery ajax upload</title>
</head>
<body>
<img id="showImg" src="" alt="">
<form role="form" id="myForm" action="http://v0.api.upyun.com/xxx" method="post" enctype="multipart/form-data">
<input type="hidden" name="policy" value="">
<input type="hidden" name="signature" value="">
<div class="form-group">
<label class="col-sm-2 control-label">说明:</label>
<div class="col-sm-10">
<p class="form-control-static ">ajax 文件上传 。</p>
</div>
</div>
<div class="form-group">
<label for="url" class="col-sm-2 control-label"><s>*</s>图片选择:</label>
<div class="col-sm-7">
<input type="file" name="fulAvatar" id="file_upload" value=""
class="form-control" placeholder="图片地址" onchange="uploadByForm();">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-7">
<a id="btnAjax" onclick=>Ajax上传</a>
</div>
</div>
</form>
<script src="http://cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript">
/**
* ajax 上传。
*/
function uploadByForm() {
//用form 表单直接 构造formData 对象; 就不需要下面的append 方法来为表单进行赋值了。
var formData = new FormData($("#myForm")[0]);
var url = "http://localhost:3000/uploader";
$.ajax({
url: url,
type: 'POST',
data: formData,
/**
* 必须false才会避开jQuery对 formdata 的默认处理
* XMLHttpRequest会对 formdata 进行正确的处理
*/
processData: false,
/**
*必须false才会自动加上正确的Content-Type
*/
contentType: false,
success: function (responseStr) {
alert(responseStr.newPath);
$("img").attr({"src": responseStr.newPath}).prependTo($("body"));
},
error: function (responseStr) {
alert(responseStr.newPath);
}
});
}
</script>
</body>
</html>
ajax上传主要用的是Jquery;这一块只是知道这么用;配置ajax的时候processData与contentType都设置为false;
还有此处用了HTML5的一个新特性;FormData;
用法如下:new FormData($("#myForm")[0])
;
关于ajax这一块我做了个尝试,就是不用html5的FormData,而是直接用$("file_upload").val()去取文件表单的值,然后通过ajax传递,结果不是很理想;
将这坨数据传到后端就可以了;
前端页面演示完了;下面是后端代码演示:
var express = require('express');
var router = express.Router();
var formidable = require('formidable'),
fs = require('fs'),
TITLE = 'formidable上传示例',
AVATAR_UPLOAD_FOLDER = '/avatar/',
domain = "http://localhost:3000";
/* 图片上传路由 */
router.post('/uploader', function(req, res) {
var form = new formidable.IncomingForm(); //创建上传表单
form.encoding = 'utf-8'; //设置编辑
form.uploadDir = 'public' + AVATAR_UPLOAD_FOLDER; //设置上传目录
form.keepExtensions = true; //保留后缀
form.maxFieldsSize = 2 * 1024 * 1024; //文件大小
form.parse(req, function(err, fields, files) {
if (err) {
res.locals.error = err;
res.render('index', { title: TITLE });
return;
}
console.log(files);
var extName = ''; //后缀名
switch (files.fulAvatar.type) {
case 'image/pjpeg':
extName = 'jpg';
break;
case 'image/jpeg':
extName = 'jpg';
break;
case 'image/png':
extName = 'png';
break;
case 'image/x-png':
extName = 'png';
break;
}
if(extName.length == 0){
res.locals.error = '只支持png和jpg格式图片';
res.render('index', { title: TITLE });
return;
}
var avatarName = Math.random() + '.' + extName;
//图片写入地址;
var newPath = form.uploadDir + avatarName;
//显示地址;
var showUrl = domain + AVATAR_UPLOAD_FOLDER + avatarName;
console.log("newPath",newPath);
fs.renameSync(files.fulAvatar.path, newPath); //重命名
res.json({
"newPath":showUrl
});
});
});
module.exports = router;
图片传到后端其实就是一段2进制字符串,保存在内存中,需要用到fs模块读取后再写入到新的目录;打印files
{ fulAvatar:
File {
domain: null,
_events: {},
_eventsCount: 0,
_maxListeners: undefined,
size: 106836,
path: 'public/avatar/upload_d75420a381af12d19db01599fd2d0b73.jpeg',
name: 'line.jpeg',
type: 'image/jpeg',
hash: null,
lastModifiedDate: 2016-12-19T15:22:47.896Z,
_writeStream:
WriteStream {
_writableState: [Object],
writable: false,
domain: null,
_events: {},
_eventsCount: 0,
_maxListeners: undefined,
path: 'public/avatar/upload_d75420a381af12d19db01599fd2d0b73.jpeg',
fd: null,
flags: 'w',
mode: 438,
start: undefined,
autoClose: true,
pos: undefined,
bytesWritten: 106836,
closed: true } } }
以上数据用fs模块读取path属性得到是就是一段2进制的字符串;
注:如果不配置express中间件,express是不能取到上传的文件的,这一块在路由回调函数的req上没有做处理。
以上的示例基本就完成一些基本功能了;
疑惑就是网上一些jquery插件上传图片利用ajax,他们的原来是声明呢 ?希望有人给解释下
找到一篇相似的文章:
补充:
var formData = new FormData();
var fileObj = document.getElementById("file_upload").files[0];
formData.append("fulAvatar", fileObj);
formData的两种用法一种是直接将表单dom直接塞进去,还有一种就是通过append填进去,但是这里要注意,填进去的是name和dom的files[0]属性;
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。