接着我之前发布的一篇文章:微信小程序上传头像的临时路径,持久化保存到服务器与数据库(nodejs后台开发)_盒子猫君的博客-CSDN博客
今天我就来解决掉之前的问题吧!
从之前的后台报错来看,获取到的tempFilePath值和avatarUrl的值相同,都是http://tmp,不过头像都已经上传成功了并存到了数据库。而在真机调试时,用户选择头像后,是无法保存到数据库和对应的文件夹中的。
经过分析后,原因是在微信小程序中,选择头像后会返回一个临时文件路径(tempFilePath)供开发者进行上传和保存操作。真机调试时,是无法直接访问和保存这个临时文件的,所以在该代码中直接读取tempFilePath可能会出现问题。
解决方案下面就有了:
使用wx.saveFile保存临时文件,并将保存的文件路径作为参数传递给wx.uploadFile进行上传操作:
onChooseAvatar(e) {
const { avatarUrl } = e.detail
wx.saveFile({
tempFilePath: avatarUrl,
success(res) {
const savedFilePath = res.savedFilePath
console.log("保存的头像文件路径:" + savedFilePath)
// 上传保存的图片
wx.uploadFile({
url: config.apiUrl + '/api/avatarUrl',
filePath: savedFilePath,
name: 'file',
formData: {
'openid': wx.getStorageSync('openid')
},
success(res) {
console.log('uploadFile响应数据:', res.data);
try {
const data = JSON.parse(res.data)
console.log('upload success');
console.log("成功获取到用户头像存入数据库:", data.path);
wx.showToast({
title: '头像上传成功',
icon: 'success',
});
} catch(e) {
console.log('返回数据不是json格式,无法解析');
wx.showToast({
title: '头像上传失败',
icon: 'error'
});
}
},
fail(res) {
console.log('upload fail');
}
})
},
fail(res) {
console.log('saveFile fail');
}
})
},
在后台路由代码中,利用Node.js的文件流将临时文件保存到指定目录,然后使用保存后的文件路径进行数据库操作:
const express = require('express');
const router = express.Router();
const sql = require('../sql');
const multer = require('multer');
const fs = require('fs');
// 设置文件上传的目录
const storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, './public/upload')
},
filename: function(req, file, cb) {
cb(null, Date.now() + '-' + file.originalname)
}
})
const upload = multer({ storage: storage })
router.post('/avatarUrl', upload.single('file'), (req, res) => {
console.log('Received file:', req.file);
console.log('Received body:', req.body);
const openid = req.body.openid;
const tempFilePath = req.file.path;
const avatarUrl = 'https://like.likehistory.top/upload/' + req.file.filename;
// 将临时文件保存到指定目录
const savedFilePath = './public/saved/' + req.file.filename;
const readStream = fs.createReadStream(tempFilePath);
const writeStream = fs.createWriteStream(savedFilePath);
readStream.pipe(writeStream);
// 创建MySQL查询
const sqlStr = 'SELECT * FROM wxusers WHERE openid = ?';
// 查询数据库
sql.query(sqlStr, [openid], function(err, result) {
if (err) {
console.error(err);
res.status(500).send('Database error');
} else {
// 检查是否有匹配的openId
if (result.length > 0) {
const sqlStr = `UPDATE wxusers SET avatarUrl = '${avatarUrl}' WHERE openid = '${openid}'`;
sql.query(sqlStr, (err, result) => {
if (err) throw err;
res.json({ path: avatarUrl });
});
console.log("更新新路径", avatarUrl);
} else {
const sqlStr = `INSERT INTO wxusers (openid, avatarUrl) VALUES ('${openid}','${avatarUrl}')`;
sql.query(sqlStr, [openid, avatarUrl], (err, result) => {
if (err) throw err;
res.json({ path: avatarUrl });
});
console.log("插入新路径", avatarUrl);
}
}
});
});
module.exports = router;
这下终于调式成功了,不过后台告诉我:wx.saveFile 即将废弃,请使用 wx.getFileSystemManager().saveFile。所以下面再修改一下微信小程序的代码:
onChooseAvatar(e) {
const { avatarUrl } = e.detail
wx.getFileSystemManager().saveFile({
tempFilePath: avatarUrl,
success(res) {
const savedFilePath = res.savedFilePath
console.log("保存的头像文件路径:" + savedFilePath)
// 上传保存的图片
wx.uploadFile({
url: config.apiUrl + '/api/avatarUrl',
filePath: savedFilePath,
name: 'file',
formData: {
'openid': wx.getStorageSync('openid')
},
success(res) {
console.log('uploadFile响应数据:', res.data);
try {
const data = JSON.parse(res.data)
console.log('upload success');
console.log("成功获取到用户头像存入数据库:", data.path);
wx.showToast({
title: '头像上传成功',
icon: 'success',
});
} catch(e) {
console.log('返回数据不是json格式,无法解析');
wx.showToast({
title: '头像上传失败',
icon: 'error'
});
}
},
fail(res) {
console.log('upload fail');
}
})
},
fail(res) {
console.log('saveFile fail');
}
})
},
最后还要在小程序的`app.json`文件中的`permission`字段中添加相关的权限配置:
"permission": {
"scope.writePhotosAlbum": {
"desc": "保存图片到相册"
},
"scope.camera": {
"desc": "拍照功能"
},
"scope.userLocation": {
"desc": "获取用户地理位置"
}
// 添加其他需要的权限配置
},
当然了,我在运行上面的代码后,还是发现了另一个问题。在用户选择相册中的图片作为头像时,由于图片是异步加载的,可能会导致上传成功后头像没有立即刷新显示。为了解决这个问题,可以在上传成功后,手动更新头像的URL,至于强制刷新页面,可有可无。文章来源:https://www.toymoban.com/news/detail-732331.html
onChooseAvatar(e) {
const { avatarUrl } = e.detail;
wx.getFileSystemManager().saveFile({
tempFilePath: avatarUrl,
success(res) {
const savedFilePath = res.savedFilePath;
console.log("保存的头像文件路径:" + savedFilePath);
// 上传保存的图片
wx.uploadFile({
url: config.apiUrl + '/api/avatarUrl',
filePath: savedFilePath,
name: 'file',
formData: {
'openid': wx.getStorageSync('openid')
},
success(res) {
console.log('uploadFile响应数据:', res.data);
try {
const data = JSON.parse(res.data);
console.log('upload success');
console.log("成功获取到用户头像存入数据库:", data.path);
// 更新头像URL
this.setData({
avatarUrl: data.path
});
// 强制刷新页面
wx.reLaunch({
url: '/pages/index/index' // 替换成你的页面路径
});
wx.showToast({
title: '头像上传成功',
icon: 'success',
});
} catch(e) {
console.log('返回数据不是json格式,无法解析');
wx.showToast({
title: '头像上传失败',
icon: 'error'
});
}
},
fail(res) {
console.log('upload fail');
}
});
},
fail(res) {
console.log('saveFile fail');
}
});
},
这篇文章就完美解决了用户上传头像的问题。大家可以参考!文章来源地址https://www.toymoban.com/news/detail-732331.html
到了这里,关于修复微信小程序获取头像的bug,微信小程序新版头像API使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!