MUI + Nodejs + Mongodb 圖片上傳的使用總結 (我寫的是頭像上傳 一樣的都是)
遇到了好多坑
1 ajax傳輸圖片要把圖片轉成base64的 我也不知道為什麼 別的方式後臺接不到
前端程式碼
function galleryImg() { //按鍵呼叫這個函式來執行從相簿選取操作
// 從相簿中選擇圖片
console.log("從相簿中選擇圖片:");
plus.gallery.pick( function(path){ //圖片的路徑
console.log(path);
compressImage(path)//壓縮圖片 執行上傳 傳遞給下面的壓縮上傳函式 從相簿的選擇是一眼的
}, function ( e ) {
console.log( "取消選擇圖片" );
}, {filter:"image"} );
}
function carmerImg(){
// var res = cmr.supportedImageResolutions[0];
// var fmt = cmr.supportedImageFormats[0];
var cmr = plus.camera.getCamera();
cmr.captureImage( function( path ){
console.log( "Capture image success: " + path );
compressImage(path)//壓縮圖片 執行上傳
},
function( error ) {
console.log( "Capture image failed: " + error.message );
},
{}
)
}
//壓縮圖片 上傳
function compressImage(path){
plus.zip.compressImage({ //壓縮圖片的一些操作 可以不壓縮 下面的canvans一樣壓縮
src:path,//原路徑
dst:path,//目標路徑
quality:100,// 壓縮的質量 100原圖
overwrite:true,//覆蓋原始檔
clip:{ //裁切
width:"100%",
height:"100%"
}
},
function(event) { //成功壓縮的回掉函式
var imgSrc = event.target;
if(!imgSrc){
mui.toast("照片不見了!請重試...")
return false;
}
var imgLoad = { //這些東西要不要無所謂
src : event.target,
size : event.size,
width : event.width,
height : event.height
}
var img = new Image();
img.src = imgLoad.src; // 傳過來的圖片路徑在這裡用。
img.onload = function() {
that = this;
//生成比例
var w = that.width,h = that.height,scale = w / h;
w =640 || w; //480 你想壓縮到多大,改這裡
h = w / scale;
//生成canvas
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
canvas.width = w;
canvas.height = h;
ctx.drawImage(that, 0, 0, w, h);
var base64 = canvas.toDataURL('image/jpg', 1 );
//console.log(base64)
var data = {};
data.base64 = base64;
data.name = userInfo.userId; //這些可以寫你想傳給後臺的資訊
console.log("上傳物件" + JSON.stringify(data.name))
plus.nativeUI.showWaiting("圖片拼命上傳中...");
mui.ajax('http://'+Url+':8888/userImg',{ //你的服務端地址
data:data,
timeout:5000,
headers:{"enctype" : "multipart/form-data"}, //這個頭部的應該可以不要
crossDomain:true,
type:"POST" ,
error:function(xhr, type, errorThrown){
plus.nativeUI.closeWaiting()
mui.toast(xhr.responseText)
mui('#sheet1').popover('toggle');
},
success:function(data, status, xhr){
$('.userimg').attr("src", imgSrc)
plus.nativeUI.closeWaiting()
mui.toast(xhr.responseText)
mui('#sheet1').popover('toggle');
}
} )}
},function(error) {
alert("壓縮上傳失敗了奧,請重試...");
});
}
mongodb $set:{key, value} 設定資料的時候 如果被設定資料沒有對應的key 它會建立這個key value 有這個key 會直接覆蓋
mongodb upadte ({key: value}) 查詢 key value 的資料型別也要對應 不然 查不到
nodejs的base64通過Buffer物件去解析儲存
如果出現 request entity too larger 記得修改bodyparser的limit
後端程式碼
var express = require('express');
var app = express();
var fs =require('fs');
var bodyParser = require('body-parser');
var multipart = require('connect-multiparty'); //在處理模組中引入第三方解析模組
var multipartMiddleware = multipart();
var MongoClient = require('mongodb').MongoClient;
app.use(bodyParser.urlencoded({ extended: true, limit:"50mb" })); //修改上傳的顯示
app.use(bodyParser.json({limit:"50mb"}));
app.use(express.static('public'))
app.use(multipart({uploadDir:'./public' }));//設定上傳檔案存放的地址。
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
res.header("X-Powered-By",' 3.2.1')
res.header("Content-Type", "application/json;charset=utf-8");
next();
});
//頭像上傳
app.post('/userImg', multipartMiddleware, function(req, res){ //引用connect - muitipart 模組
console.log(req.body.name)
// var parseInt()
//不要把base64直接通過query.body傳過來 不然很麻煩 轉格式什麼的
var base64 = req.body.base64.replace(/^data:image\/\w+;base64,/, "");//去掉圖片base64碼前面部分data:image/png;base64//
var dataBuffer = new Buffer(base64, 'base64'); //把base64碼轉成buffer物件,
console.log('dataBuffer是否是Buffer物件:'+Buffer.isBuffer(dataBuffer));
//驗證路徑是否存在
fs.exists("public/img/userImg/"+ req.body.name + "/", function(exits){ //驗證路徑 這些都是你放圖片的路徑 存在的話就直接覆蓋 不存在的話建立路徑再覆蓋
if(exits == true) {
console.log("路徑存在")
fs.writeFile("public/img/userImg/"+ req.body.name + "/" + "userHeaderImg.jpg", dataBuffer, function(err){ //寫入檔案
if(err){
res.status(500)
res.send({success:"上傳圖片失敗,路徑覆蓋出錯"})
} else {
MongoClient.connect('mongodb://dbadmin:[email protected]:27017/', function(err, db){ //這裡的邏輯我寫的是如果上傳了頭像 更新使用者的頭像資料 然後本地的客戶端就會獲取這個值來更新頭像 根據自己的邏輯寫
var userDB = db.db("ergou");
userDB.collection("users", function(err, users){
// console.log("查詢" +{userId:req.body.name} )
// console.log(typeof 0)
// console.log(typeof parseInt(req.body.name))
// users.find({userId: parseInt(req.body.name) }, function(err, items){
// items.toArray(function(err, item){
// console.log(item)
// })
// })
/*記住數字的查詢要變成數字 不能是字串 因為在mongo裡會當成 ‘0’*/
users.update({userId: parseInt(req.body.name)}, {$set:{headerImg:true}}, function(err, results){ //這裡注意了 這裡的查詢的資料型別要和你的後臺儲存的型別一致
// console.log(results)
if(err){
res.status(500)
res.send({success:"儲存到資料庫的過程中出錯了,請重試"})
} else {
res.status(200)
res.send({success:"圖片上傳成功"})
}
})
})
})
}
})
} else { //如果路徑不存在 建立路徑 並且寫入圖
fs.mkdir("public/img/userImg/"+ req.body.name , function(err){
if(err) {
console.log("建立目錄失敗")
res.status(500);
res.send({success:"儲存圖片到伺服器的過程失敗了"})
} else {
fs.writeFile("public/img/userImg/"+ req.body.name +"/"+ "userHeaderImg.jpg", dataBuffer, function(err){
MongoClient.connect('mongodb://dbadmin:[email protected]:27017/', function(err, db){
var userDB = db.db("ergou");
userDB.collection("users", function(err, users){
// users.find({userId:req.body.name}, function(err, items){
// items.toArray(function(err, item){
// console.log(item)
// })
// })
users.update({userId: parseInt(req.body.name)}, {$set:{headerImg:true}}, function(err, results){//$set 有酒更新 沒有就建立
// console.log(results)
if(err){
res.status(500)
res.send({success:"儲存到資料庫的過程中出錯了,請重試"})
} else {
res.status(200)
res.send({success:"圖片上傳成功"})
}
})
})
})
})
}
})
} //else 結束
})//路徑的驗證結束
//console.log(req.body.base64)
})