uniapp(h5)实现图片上传功能

记录一下项目中遇到的问题

需求是h5有个签名板,当用户签完名后需要把签名照片上传给后端

第一步:实现签名版功能--返回base64格式图片

<template>
  <view>
    <view class="sign-content">
      <view>
        <view class="reset" @click="backClick" style="position:fixed;bottom: 466rpx;background:#fff;">返回</view>

        <view class="reset" @click="clearClick" style="position:fixed;bottom: 266rpx;background:#fff;">重写</view>

        <view class="reset" @click="saveClick" style="position:fixed;bottom: 66rpx;background: #39b54a;color:#fff;">确定
        </view>
      </view>

      <canvas class="sign" canvas-id="sign" @touchmove="move" @touchstart="start" @touchend="end" @touchcancel="cancel"
        @longtap="tap" disable-scroll="true" @error="error"></canvas>

      <view>
        <view style="transform: rotate(90deg);text-align: center;position:fixed;width:130rpx;right:-14rpx;top:46%;">签名板
        </view>
      </view>
    </view>
  </view>
</template>

<script>
  let content = null;
  let touchs = [];

  export default {
    data() {
      return {
        isMove: false,
        createCanvas: false,
        outW: 0,
        outH: 0,
        windowsH: 0,
        windowsW: 0
      };
    },
    onLoad: function(options) {
      //获得Canvas的上下文
      content = uni.createCanvasContext('sign');
      this.windowsH = uni.getSystemInfoSync().windowHeight;
      this.windowsW = uni.getSystemInfoSync().windowWidth;
      //设置线的颜色
      content.setStrokeStyle('#000000');
      //设置线的宽度
      content.setLineWidth(5);
      //设置线两端端点样式更加圆润
      content.setLineCap('round');
      //设置两条线连接处更加圆润
      content.setLineJoin('round');
      // content.setFillStyle('white')
      // content.fillRect(0, 0, 750, 700)
      // content.draw()
    },
    methods: {
      backClick: function() {
        uni.navigateBack({
          delta: 1
        });
      },
      // 画布的触摸移动开始手势响应
      start: function(event) {
        // console.log("触摸开始" + event.changedTouches[0].x);
        // console.log("触摸开始" + event.
<think>我们正在讨论UniAppH5页面上传图片实现。根据引用[1],我们可以使用`uni.chooseImage`选择图片,然后使用`uni.uploadFile`上传图片。在H5环境下,需要注意文件对象的获取方式。 具体步骤: 1. 使用`uni.chooseImage`选择图片,在H5环境下,返回的`res.tempFiles[0]`是一个File对象。 2. 使用`uni.uploadFile`上传,在H5环境下,需要以`files`数组的形式传递文件,数组中的每个元素是一个对象,包含`name`(后端约定的key)和`file`(File对象)属性。 注意:在微信小程序(MP-WEIXIN)环境下,使用`res.tempFilePaths[0]`获取临时文件路径,然后以`filePath`参数传递。 因此,针对H5环境的代码实现如下: ```javascript uni.chooseImage({ count: 1, // 选择一张图片 sizeType: ['original', 'compressed'], // 可以选择原图或压缩图 sourceType: ['album', 'camera'], // 从相册或相机选择 success: (res) => { // 在H5环境下,使用res.tempFiles[0]获取文件对象 let fileObj = res.tempFiles[0]; // 上传文件 uni.uploadFile({ url: '你的服务器地址', files: [{ name: 'file', // 这里和后端约定的key,比如'file' file: fileObj }], success: (uploadRes) => { // 上传成功处理 console.log(uploadRes.data); }, fail: (error) => { console.error(error); } }); } }); ``` 注意:以上代码只适用于H5环境。如果需要同时兼容小程序和H5,可以使用条件编译,如引用[1]所示。 例如,同时兼容H5和微信小程序: ```javascript uni.chooseImage({ count: 1, sizeType: ['original', 'compressed'], sourceType: ['album', 'camera'], success: (res) => { let filePath = ''; // #ifdef H5 filePath = res.tempFiles[0]; // #endif // #ifdef MP-WEIXIN filePath = res.tempFilePaths[0]; // #endif // 上传文件 uni.uploadFile({ url: '你的服务器地址', // #ifdef H5 files: [{ name: 'file', // 和后端约定的key file: filePath }], // #endif // #ifdef MP-WEIXIN filePath: filePath, name: 'file', // 和后端约定的key // #endif success: (uploadRes) => { console.log(uploadRes.data); }, fail: (error) => { console.error(error); } }); } }); ``` 这样,代码就可以在H5和微信小程序两个平台上运行。 另外,需要注意的是,H5环境下上传文件时,`uni.uploadFile`的`files`参数是一个数组,可以同时上传多个文件。而微信小程序环境下,`filePath`是临时文件路径,通过`name`指定后端接收的字段名。 请根据实际后端接口调整`url`和`name`字段。 §§相关问题§§ 1. 在UniApp中,如何实现同时选择多张图片上传? 2. 在H5环境下,如何限制上传图片的大小和类型? 3. 如何显示上传进度?</think>在 UniApp实现 H5 页面上传图片功能,主要使用 `uni.chooseImage` 选择图片和 `uni.uploadFile` 上传文件。以下是完整实现方案: ### 核心代码实现 ```javascript <template> <view> <button @click="chooseImage">选择图片</button> <image v-if="imageUrl" :src="imageUrl" mode="aspectFit"></image> </view> </template> <script> export default { data() { return { imageUrl: "", // 预览图地址 fileObj: null // 文件对象 }; }, methods: { // 选择图片 chooseImage() { uni.chooseImage({ count: 1, sizeType: ['compressed'], // 压缩图 sourceType: ['album', 'camera'], // 相册或相机 success: (res) => { // H5平台处理 // #ifdef H5 this.fileObj = res.tempFiles[0]; this.imageUrl = URL.createObjectURL(this.fileObj); this.uploadImage(); // #endif } }); }, // 上传图片 uploadImage() { uni.uploadFile({ url: 'https://your-server.com/upload', // 替换为实际接口 files: [{ name: 'file', // 后端接收的字段名 file: this.fileObj }], formData: { // 附加参数 userId: '123' }, success: (res) => { console.log('上传成功', JSON.parse(res.data)); uni.showToast({ title: '上传成功' }); }, fail: (err) => { console.error('上传失败', err); uni.showToast({ title: '上传失败', icon: 'error' }); } }); } } }; </script> ``` ### 关键点说明 1. **平台差异处理**: - H5 使用 `res.tempFiles[0]` 获取文件对象[^1] - 小程序使用 `res.tempFilePaths[0]`(需条件编译) 2. **上传参数**: - `files`: 数组格式,包含 `name`(后端接收字段)和 `file`(文件对象) - `formData`: 可附加文本参数(如用户ID) 3. **预览功能**: - 通过 `URL.createObjectURL()` 生成预览图 - `<image>` 组件显示预览 ### 注意事项 1. **H5 特殊限制**: - 需要后端支持 `multipart/form-data` 格式 - 可能需要配置跨域(CORS) 2. **安全优化**: ```javascript // 上传前校验文件类型 if (!['image/jpeg', 'image/png'].includes(this.fileObj.type)) { uni.showToast({ title: '仅支持JPG/PNG格式' }); return; } // 限制文件大小(2MB) if (this.fileObj.size > 2 * 1024 * 1024) { uni.showToast({ title: '文件不能超过2MB' }); return; } ``` 3. **多图上传**: 修改 `count` 参数并遍历文件数组: ```javascript // 选择多图 uni.chooseImage({ count: 3, // 最多3张 success: (res) => { res.tempFiles.forEach(file => { this.uploadFile(file); // 单独处理每个文件 }) } }) ``` ### 完整工作流程 1. 用户点击按钮触发 `chooseImage()` 2. 调用设备相册/相机选择图片 3. 生成预览图并存储文件对象 4. 构造上传参数(含文件和其他表单数据) 5. 发送到服务器处理 6. 根据响应结果提示用户 > 提示:测试时可用免费图床接口 `https://httpbin.org/post` 作为临时上传地址
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值