
正文
如何把前端用ajax发过来的图片传到node上,并且用node保存在oss图片服务器上?
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
一:只上传一张图片
1.1:node需要安装的插件,先安好
npm install ali-oss uuid co --save
A、ali-oss
用途:aliyun OSS(Object Storage Service) js client for Node and Browser env;
文档地址:https://www.npmjs.com/package/ali-oss
学习参考地址:https://help.aliyun.com/document_detail/31927.html?spm=a2c4g.11186623.2.10.26884367L6zw5e#concept-qp2-g4y-5db
B、co
用途:处理Generator 函数的插件返回promise
文档地址:https://www.npmjs.com/package/co
C、uuid:
用途:是简单,快速生成RFC4122 UUIDS的插件;
文档地址:https://www.npmjs.com/package/uuid;
1.2:前端上传代码
A、 html代码是用的weui的弹框,里面加了weui的upload样式,自己再用css改了一下,代码如下
<div id="dialog_upload" class="out_myDialog" style="display: none;">
<div class="weui-mask"></div>
<div class="weui-dialog">
<div class="weui-dialog__hd">
<strong class="weui-dialog__title">
select the picture to upload!
</strong>
</div>
<div class="weui-dialog__bd" id="ld-dialog__bd">
<div class="weui-uploader__input-box">
<img class="uploadImg" src="" alt="">
<input id="uploaderInput" class="weui-uploader__input" type="file" accept="image/*">
</div>
</div>
<div class="weui-dialog__ft">
<a href="javascript:;" class="weui-dialog__btn weui-dialog__btn_default cart_cancle">Cancle</a>
<a href="javascript:;" class="weui-dialog__btn weui-dialog__btn_primary confirm_delect">Confirm</a>
</div>
</div>
</div>
B、 css改动这里不涉及,自己写吧
C、 前端样式如下

D、 js实现展示图片和保存图片到formdata里面,代码如下:
//点击file类型的input的事件
$("#uploaderInput").on("change",function(){
var files = $(this).prop('files'); //获取图片的文件
if(files.length>0){
hasImg = true;
var windowURL = window.URL || window.webkitURL;
var src=windowURL.createObjectURL(files[0]);//建临时路径
$(".uploadImg").attr({src:src}) //把选的图片展示出来
// console.log(files[0]);
headImgFordata = new FormData();
headImgFordata.append('avatar', files[0]); //文件保存在formdata里面,便于提交到后台
}else{
hasImg = false;
headImgFordata = null;
} })
选完图片的样子:

E、 上传图片到node的js代码:
//点击确认按钮的事件,把数据传到node
function toConfirmLay(){ //确认上传头像点击事件
if(!hasImg){
lopdealsToast("error","Please select a valid picture !!",2000,false) //自己封装的展示错误提示的方法
return false;
}
$.ajax({
type:"POST",
url:apiUrl["apipostUserUpHead"], //接收的地址
data:headImgFordata,
dataType: 'JSON',
processData: false,
contentType: false,
success:function(res){
console.log(res)
if(res.code == 5200){//请求成功 //。。。自己处理发送成的时候的代码。。。。 }else{ //请求失败
lopdealsToast("error","Fail !!!",1500,false)
}
},
error:function(res){
lopdealsToast("error","Fail !!!",1500,false)
}
});
}
1.3:node的接收和把图片上传到oss
//在node端的接收和处理这个上传接口的地方写下面代码//先引入下面这些插件
const formidable = require('formidable');
const OSS = require('ali-oss');
const co = require('co');
const fs=require('fs');
const config = require('./common/ossConfig.js');//配置oss的文件
const uuidv1 = require('uuid/v1'); //生成随机数//。。。。 省略的代码//处理该接口的方法
。。。function(req,res){
try{
var form = new formidable.IncomingForm();
const client = new OSS({ //oss
region: config.region, // 域名所在地
accessKeyId: config.accessKeyId,
accessKeySecret: config.accessKeySecret,
bucket:config.bucket
});
//设置文件上传存放地址
//执行里面的回调函数的时候,表单已经全部接收完毕了。
form.uploadDir=config.localImgpath; //这个一定要设置否则是默认地址找不到会报错
form.parse(req, function(err, fields, files) {
if(err){
return commonError.server(req,res,"",err,false);
}else{
const extName=files.avatar.name; //获得图片的名字和后缀名
const randomNum=uuidv1(); //生成随机数
const oldPath = files.avatar.path ;
const newPath=config.localImgpath+"/upload_"+ randomNum + extName; fs.rename(oldPath, newPath,function(err){ //存图片
if(err){
return commonError.server(req,res,"",err,false);
}else{
const key = "upload_"+randomNum+extName;
co(function* () {
// client.useBucket(ali_oss.bucket);
const result = yield client.put(key, newPath); //上传到oss
const imageSrc = config.imgPath + result.name;
fs.unlinkSync(newPath); /*删除文件*/
return res.json({code:'5200',data:[imageSrc]});
}).catch(function (err) {
fs.unlinkSync(newPath); /*删除文件*/
return commonError.web(req,res,"",error,false);
});
}
});
} }) }catch(error){
return commonError.web(req,res,"",error,false);
};
}//.........省略的
------------------------------
二:上传多张图片到oss
2.1:页面的修改
// 1.在input上加上 mutipart的属性,可以一次选多张图片 <input name="img" id="uploaderInput" class="weui-uploader__input" multiple type="file" accept="image/*">// 2. 在原来的传一张图append,到用循环append多张到formdata里面 headImgFordata = new FormData(); headImgFordata = new FormData();
for(var i=0, f; f=files[i]; i++){
headImgFordata.append('images', f);
}
2.2:node端的代码:
***
const multer = require('multer');
const moment = require('moment');*** postUserUpHead2: function (req, res) {/*一次上传多张图片到oss */
const uploadMyDir = `./static/public/mobile/serverImg/${moment().format('YYYYMMDD')}` //存放图片的地址
fs.mkdirSync(uploadMyDir, {
recursive: true // recursive 使用递归创建目录,如果父目录不存在会先创建
}) // OSS实例化
const clientMy = new OSS({
region: config.region, // 域名所在地
accessKeyId: config.accessKeyId,
accessKeySecret: config.accessKeySecret,
bucket: config.bucket
}); const storage = multer.diskStorage({ //设置上传中间件
destination: function (req, file, cb) { //上传路径
cb(null, uploadMyDir)
},
filename: function (req, file, cb) {//上传之后的文件名
cb(null, Date.now() + '-' + file.originalname)
}
}) //设置multer的上传
const uploadMulter = multer({
storage
}).array('images') //在前台append的formdata的名字要和这个一致 uploadMulter(req, res, function (err) {
if (err) {
return commonError.web(req, res, "", err, false);
} else {
const randomNum = uuidv1(); //生成唯一数字
const key = "upload_" + randomNum;
co(function* () {
let results = []
const reqFiles = req.files
for (var i = 0; i < reqFiles.length; i++) {
results[i] = yield clientMy.put(key, reqFiles[i].path)
fs.unlinkSync(reqFiles[i].path); /*删除文件*/
}
let imageSrc = [];
results.forEach((item) => {
imageSrc.push(config.imgPath + item.name)
})
return res.json({ code: '5200', data: imageSrc });
// return res.json({data:imgPath})
}).catch(function (err) {
return commonError.web(req, res, "", err, false);
});
}
})
}







