微信小程序上传图片后立即展示该图片的最佳实践

业务场景及实践遇到的问题

  1. 业务场景
  • 微信小程序内,需要实现一个类似微博的图文列表,支持顶部新增图文,新增成功之后,列表立即加载新增的图文记录。
  1. 遇到的问题
  • 微信小程序对应的服务端使用了微信云托管,所以选择使用云托管中的对象存储服务来保存图片。
  • 使用wx.cloud.uploadFile上传图片,图片上传成功后,image标签对应的src使用官方推荐的loadcos转换方法来转换fileId得到用于公开访问的url,但是图片都不能正常展示出来。
javascript 复制代码
function loadcos(url){
  var res = url
  if (url.indexOf('cloud://') === 0) {
    var first = url.indexOf('.')
    var end = url.indexOf('/', first)
    res = 'https://' + url.slice(first + 1, end) + '.tcb.qcloud.la/' + url.slice(end + 1, url.length)
  }
  return res
}

module.exports={
  loadcos:loadcos
}

在微信开发者工具中会看到有两次对应的图片网络请求:

  • 第一个请求的域名是 tcb.qcloud.la,而第二个请求的域名是 cos.ap-shanghai.myqcloud.com

  • 这表明可能存在两种不同的访问路径:

    • tcb.qcloud.la 是微信云存储的默认域名。
    • cos.ap-shanghai.myqcloud.com 是腾讯云 COS 的 CDN 域名。
  • 第一个请求返回404,第二个请求返回No content

分析可能的原因:tcb.qcloud.la域名的url是loadcos方法转换得到的,返回404,大概率是因为云存储有做读写分离,图片上传到写服务,但是还没同步到读服务;cos.ap-shanghai.myqcloud.com域名的url请求应该是微信小程序内部实现的机制,在不能正确从云存储加载到图片时,再请求一遍存储对应区域的CDN,多做一次尝试,但是读取的还是云存储的读服务,所以还是不能正确获取图片文件。

解决方案

在图片上传到云端后需要立即展示的情况下。通过直接使用本地临时文件路径(tmpFilePath)作为 <image>src 属性值,可以绕过网络延迟和云存储同步的问题,从而实现图片的即时加载。

以下是详细分析:


为什么使用 tmpFilePath 能立即加载图片?

  1. 本地文件路径

    • tmpFilePath 是用户选择图片时生成的本地临时文件路径(例如:wx.chooseImage 返回的 tempFilePaths)。
    • 这个路径指向的是设备本地的文件,因此可以直接读取,无需等待网络传输或云存储同步。
  2. 避免网络延迟

    • 上传图片到云端后,文件可能需要时间写入存储系统,并同步到 CDN。如果直接使用云端路径(如 fileIDCDN URL),可能会因为同步延迟导致图片无法立即加载。
    • 使用 tmpFilePath 可以完全避免这些网络问题。
  3. 用户体验提升

    • 用户在选择图片后,可以立即看到图片预览,而无需等待上传完成。这种即时反馈显著提升了用户体验。

代码示例

以下是一个完整的代码示例,展示如何在微信小程序中实现这一方案:

javascript 复制代码
Page({
  data: {
    tempFilePath: '', // 用于存储本地临时文件路径
    cloudFileURL: '', // 用于存储云端文件 URL
  },

  // 选择图片并显示临时文件
  chooseImage() {
    wx.chooseImage({
      count: 1, // 允许选择一张图片
      success: (res) => {
        const tempFilePath = res.tempFilePaths[0]; // 获取临时文件路径
        this.setData({
          tempFilePath: tempFilePath, // 设置临时文件路径为图片 src
        });

        // 上传图片到云端
        this.uploadImage(tempFilePath);
      },
      fail: (err) => {
        console.error('选择图片失败:', err);
      },
    });
  },

  // 上传图片到云端
  uploadImage(tempFilePath) {
    wx.cloud.uploadFile({
      cloudPath: `images/${Date.now()}.jpg`, // 云端存储路径
      filePath: tempFilePath, // 本地临时文件路径
      success: (uploadRes) => {
        console.log('图片上传成功:', uploadRes.fileID);

        // 获取云端文件的临时访问链接
        wx.cloud.getTempFileURL({
          fileList: [uploadRes.fileID],
          success: (urlRes) => {
            const cloudFileURL = urlRes.fileList[0].tempFileURL;
            this.setData({
              cloudFileURL: cloudFileURL, // 更新云端文件 URL
            });
            console.log('获取云端文件 URL 成功:', cloudFileURL);
          },
          fail: (err) => {
            console.error('获取云端文件 URL 失败:', err);
          },
        });
      },
      fail: (err) => {
        console.error('图片上传失败:', err);
      },
    });
  },
});

WXML 示例

html 复制代码
<view>
  <!-- 显示图片 -->
  <image 
    :src="cloudFileURL || tempFilePath" 
    mode="aspectFit" 
    style="width: 100%; height: 300px;">
  </image>

  <!-- 选择图片按钮 -->
  <button bindtap="chooseImage">选择图片</button>
</view>

逻辑解释

  1. 选择图片

    • 用户点击按钮触发 chooseImage 方法。
    • 使用 wx.chooseImage 选择图片,获取临时文件路径 tempFilePath
    • tempFilePath 设置为 <image>src,立即显示图片。
  2. 上传图片

    • 同时调用 uploadImage 方法将图片上传到云端。
    • 上传完成后,通过 wx.cloud.getTempFileURL 获取云端文件的临时访问链接。
  3. 更新云端 URL

    • 当云端文件 URL 可用时,更新 cloudFileURL
    • <image>src 会自动切换为云端 URL,确保图片持久化。

优点

  • 即时显示:用户选择图片后,图片立即显示,无需等待上传完成。
  • 无缝切换:当云端 URL 可用时,图片源会自动切换为云端地址,保证后续访问的稳定性。
  • 减少延迟:避免了因网络延迟或云存储同步导致的图片加载失败。

注意事项

  1. 临时文件的有效期

    • tmpFilePath 是一个临时文件路径,通常只在当前页面或会话中有效。如果需要长期保存图片,必须上传到云端并使用云端 URL。
  2. 错误处理

    • 如果上传失败,确保有相应的错误提示机制,并允许用户重新上传。
  3. 性能优化

    • 如果图片较大,可以在上传前进行压缩(如使用 wx.compressImage),以减少上传时间和流量消耗。

总结

通过使用 tmpFilePath 作为图片的初始 src,可以实现图片的即时加载,显著提升用户体验。同时,结合云端 URL 的动态切换,可以确保图片的持久化和长期可用性。这种方案适用于大多数需要快速预览图片的场景,是微信小程序开发中常用的最佳实践之一。

相关推荐
m0_47119963几秒前
【自动化】前端开发,如何将 Jenkins 与 Gitee 结合实现自动化的持续集成(构建)和持续部署(发布)
前端·gitee·自动化·jenkins
w***95492 分钟前
spring-boot-starter和spring-boot-starter-web的关联
前端
Moment6 分钟前
富文本编辑器技术选型,到底是 Prosemirror 还是 Tiptap 好 ❓❓❓
前端·javascript·面试
xkxnq10 分钟前
第二阶段:Vue 组件化开发(第 18天)
前端·javascript·vue.js
晓得迷路了12 分钟前
栗子前端技术周刊第 112 期 - Rspack 1.7、2025 JS 新星榜单、HTML 状态调查...
前端·javascript·html
怕浪猫14 分钟前
React从入门到出门 第五章 React Router 配置与原理初探
前端·javascript·react.js
jinmo_C++15 分钟前
从零开始学前端 · HTML 基础篇(一):认识 HTML 与页面结构
前端·html·状态模式
鹏多多21 分钟前
前端2025年终总结:借着AI做大做强再创辉煌
前端·javascript
小Tomkk29 分钟前
⭐️ StarRocks Web 使用介绍与实战指南
前端·ffmpeg
不一样的少年_33 分钟前
产品催: 1 天优化 Vue 官网 SEO?我用这个插件半天搞定(不重构 Nuxt)
前端·javascript·vue.js