uniapp上传图片至node后端并存储图片
uniapp上传图片至node后端并存储图片,返回图片的网络地址,方便同其他数据一起存储
·
前端请求
一开始考虑使用现成的图床api上传,但是图床上传要求必须是file格式的图片对象,不支持uni自带的uploadFile上传,然后考虑在node上发送请求,但是试了很多种方法还是获取不到需要的file格式对象,所以使用node管理图片
1将图片通过uni.uploadFile上传到node上
let imgurl = await this.$http.uploadImg(this.imageList[0]); //发送图片对象console.log(imgurl) //上传图片
//请求api
uploadImg: function(data) { //上传图片
console.log(data)
return new Promise((resolve, reject) => {
uni.uploadFile({ //上传代码
url: BASE_URL + '/my/upload', //本地node.js服务器地址
filePath: data,
name: "file", //这个东西有点类似与 form表单中的name值 在后面也需要这个
success: function(res) {
resolve(res); ///返回!!!!!!
console.log('res');
console.log(res);
},
fail: function(e) {
reject(e)
console.log(e)
}
})
})
},
node写法
这里使用一个很容易想到的方法,获取上传图片之后随机数重命名并修改图片路径,开放存储路径,达到可以访问的效果
开放图片文件夹
app.use('/img', express.static('public/images'))
修改路径与存储需要预设存储图片的文件夹
const express = require('express')
const router = express.Router()
const my_handler = require('../router_handler/my')
const path = require('path')
const fs = require('fs');
const request = require("request");
const db = require("../db");
//设置临时目录 存放上传的图片
const upload = multer({dest: "tmp/"});
// 接受客户端上传的图片
router.post("/upload", upload.single("file"), (req, res) => {
let imgFile = req.file;//获取图片上传的资源
console.log(imgFile)
let tmp = imgFile.path;//获取临时资源
let ext = path.extname(imgFile.originalname);//利用path模块获取 用户上传图片的 后缀名
let newName = "" + (new Date().getTime()) + Math.round(Math.random() * 10000) + ext; //给用户上传的图片重新命名 防止重名
let newPath = "../public/images/" + newName; //给图片设置存放目录 提前给当前文件夹下建立一个 images文件夹 !!!!
let fileData = fs.readFileSync(tmp);//将上传到服务器上的临时资源 读取到 一个变量里面
fs.writeFileSync(path.join(__dirname, newPath), fileData);//重新书写图片文件 写入到指定的文件夹下
console.log('http://127.0.0.1:3007/img/' + newName)
let newurl = 'http://127.0.0.1:3007/img/' + newName;
res.send(newurl);//上传成功之后 给客户端响应
// http://127.0.0.1:3007/img/1647057754040334.jpg
})
然后返回得到图片在服务器上的地址,连同其他信息进行最后信息发送,从而在数据库里存储图片地址。
页面完整代码
<template>
<view class="page">
<uni-nav-bar color="#FFFFFF" leftIcon="back" backgroundColor="#3088C9" @clickLeft="backToLastPage()"
title="提交申请信息"></uni-nav-bar>
<view class="feedback-body feedback-uploader">
<view class="uni-uploader">
<view class="uni-uploader-head">
<view class="uni-uploader-title"></view>
<view class="uni-uploader-info"></view>
</view>
<view class="uni-uploader-body">
<view class="uni-uploader__files">
<block v-for="(image,index) in imageList" :key="index">
<view class="uni-uploader__file" style="position: relative;">
<image class="uni-uploader__img" :src="image" @tap="previewImage(index)"></image>
<view class="close-view" @click="close(index)">x</view>
</view>
</block>
</view>
</view>
<view class="uni-uploader__input-box" v-if="imageList.length ==0">
<view class="uni-uploader__input" @tap="chooseImg"></view>
</view>
</view>
</view>
<view class="btnline">
<view class="btnlable">时间</view>
<view class="btnres">
<view class="uni-input">{{time}}</view>
</view>
</view>
<view class="btnline">
<view class="btnlable">名字</view>
<view class="btnres">
<input class="uni-input" maxlength='4' @blur='nameInput'></input>
</view>
</view>
<view class="btnline">
<view class="btnlable">地址</view>
<view class="btnres">
<input class="uni-input" maxlength="30" @blur='positionInput'></input>
</view>
</view>
<view class="btnline">
<view class="btnlable">电话</view>
<view class="btnres">
<input class="uni-input" type="number" maxlength='12' @blur='phoneInput'></input>
</view>
</view>
<button class="btn" @tap="send">提交</button>
</view>
</template>
<script>
import {
formatTime
} from "../../utils/formatedate.js";
var _self; //this
export default {
mounted() {
this.time = formatTime(new Date())
console.log(this.time); //时间
},
data() {
return {
imageList: [],
time: '',
nameStr: '',
phoneStr: '',
positionStr: '',
nameStrValid: '必填',
index: 0,
sendDate: {
score: 0,
content: "",
contact: ""
}
}
},
created() {
_self = this; //全局的this
},
onLoad: function(option) {},
methods: {
nameInput: function(event) {
this.nameStr = event.target.value;
if (this.nameStr.length <= 0) {
this.nameStrValid = '姓名不能为空';
} else {
this.nameStrValid = '验证通过';
}
},
phoneInput: function(event) {
this.phoneStr = event.target.value;
},
positionInput: function(event) {
this.positionStr = event.target.value;
},
close(e) {
this.imageList.splice(e, 1);
},
chooseMsg() { //快速输入
uni.showActionSheet({
itemList: this.msgContents,
success: (res) => { //从底部向上弹出操作菜单
this.sendDate.content = this.msgContents[res.tapIndex];
}
})
},
backToLastPage() {
uni.navigateBack();
},
chooseImg(index) { //选择图片
uni.chooseImage({
sourceType: ["camera", 'album'],
count: 1 - this.imageList.length,
sizeType: "compressed",
success: function(res) {
_self.imageList = res.tempFilePaths //一张图片
}
})
},
previewImage(index) { //预览图片
uni.previewImage({
urls: this.imageList,
current: this.imageList[index]
});
},
async send() { //发送申请
console.log('开始发现');
if (this.imageList.length === 0) {
uni.showModal({ //弹窗提示
content: '至少选择一张图片',
showCancel: false
})
return
}
if (this.nameStr.replace(/\s*/g, "") === '') {
uni.showModal({ //弹窗提示
content: '姓名不为空',
showCancel: false
})
}
let imgurl = await this.$http.uploadImg(this.imageList[0]); //发送图片对象
console.log(imgurl) //上传图片
let data = {
owner_id: getApp().globalData.id,
phone: this.phoneStr,
pos: this.positionStr,
owner_img: imgurl.data,
time: this.time,
name: this.nameStr,
}
console.log('data:')
console.log(data)
let result = await this.$http.addmaster(data)
uni.showToast({
title: '已发送申请',
duration: 2000
});
if (result.data.status === 0) {
uni.showToast({
title: '申请成功',
duration: 2000
});
getApp().globalData.ismaster = true
}
},
}
}
</script>
<style>
page {
background-color: #EFEFF4;
}
.input-view {
font-size: 28rpx;
}
.close-view {
text-align: center;
line-height: 14px;
height: 16px;
width: 16px;
border-radius: 50%;
background: #FF5053;
color: #FFFFFF;
position: absolute;
top: -6px;
right: -4px;
font-size: 12px;
}
.feedback-body {
background: #fff;
}
.feedback-uploader {
padding: 22rpx 20rpx;
}
.uni-uploader {
flex: 1;
flex-direction: column;
}
.uni-uploader-head {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.uni-uploader-info {
color: #B2B2B2;
}
.uni-uploader-body {
margin-top: 16rpx;
}
.uni-uploader__files {
margin-top: 30px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.uni-uploader__file {
margin-left: 100px;
width: 300rpx;
height: 300rpx;
}
.uni-uploader__img {
display: block;
width: 300rpx;
height: 300rpx;
}
.uni-uploader__input-box {
position: relative;
margin-left: 100px;
width: 300rpx;
height: 300rpx;
border: 2rpx solid #D9D9D9;
}
.uni-uploader__input-box:before,
.uni-uploader__input-box:after {
/* 内部线条 */
content: " ";
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
background-color: #D9D9D9;
}
.uni-uploader__input-box:before {
width: 4rpx;
height: 79rpx;
}
.uni-uploader__input-box:after {
width: 79rpx;
height: 4rpx;
}
.uni-uploader__input-box:active {
border-color: #999999;
}
.uni-uploader__input-box:active:before,
.uni-uploader__input-box:active:after {
background-color: #999999;
}
.uni-uploader__input {
position: absolute;
z-index: 1;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
}
.btnline {
margin-top: 20rpx;
height: 80rpx;
width: 100%;
}
.btnline2 {
margin-top: 10rpx;
height: 870rpx;
width: 100%;
}
.btnlable {
margin-left: 10rpx;
height: 80rpx;
font-size: 30rpx;
width: 26%;
text-align: center;
line-height: 80rpx;
background: #FFFFFF;
border: solid 1px #F0F0F0;
border-radius: 6px;
float: left;
}
.btnres {
margin-left: 10rpx;
height: 80rpx;
font-size: 30rpx;
width: 68%;
text-align: center;
line-height: 80rpx;
background: #FFFFFF;
border: solid 1px #F0F0F0;
border-radius: 6px;
float: left;
}
.btndate {
margin-left: 10rpx;
height: 80rpx;
font-size: 30rpx;
width: 40%;
text-align: center;
line-height: 80rpx;
background: #FFFFFF;
border: solid 1px #F0F0F0;
border-radius: 6px;
float: left;
}
.btn {
margin-top: 100rpx;
margin-left: 8%;
height: 80rpx;
font-size: 30rpx;
width: 84%;
text-align: center;
line-height: 80rpx;
color: #FFFFFF;
background: #f9624f;
border: solid 1px #F0F0F0;
border-radius: 6px;
float: left;
}
</style>
更多推荐
已为社区贡献2条内容
所有评论(0)