小程序雲開發--雲函數上傳文件或圖片 base64


 

 

雲函數開發遇到的問題

在微信雲開發環境當中,普通的用戶並沒有往雲存儲內寫入文件的權限

所以普通用戶想要使用wx.cloud.uploadFile顯然是不現實的

但是我們同時也知道,雲函數是后台服務端,具有管理員權限,只要能調用雲函數上傳文件就可以解決這個問題了

參照官方文檔中雲函數的寫法

 

const cloud = require('wx-server-sdk')
const fs = require('fs')
const path = require('path')

exports.main = async (event, context) => {
  const fileStream = fs.createReadStream(path.join(__dirname, 'demo.jpg'))
  return await cloud.uploadFile({
    cloudPath: 'demo.jpg',
    fileContent: fileStream,
  })
}

 

 

官方文檔寫的雲里霧里,並不是這么容易理解

_dirname代表的是文件根目錄,官方文檔能實現的功能貌似只是移動雲存儲空間中的文件,並不能操作本地文件

 

解決方案

 

只上傳文件路徑是不能把本地文件成功上傳到雲存儲的,但是我們可以將本地文件進行 進制 編碼 轉化為字節流上傳到雲函數中,

再在雲函數的操作中把字節或文件轉化為相對應的格式

 

微信小程序文檔為我們提供了一個很好的用於編碼文件的功能函數

wx.getFileSystemManager()

利用這個函數,可以把圖片編碼成為base64 的形式上傳到雲函數

如果是多個圖片上傳,只需要遍歷即可

 

wx.getFileSystemManager().readFile({
        filePath: that.data.images[i], //選擇圖片返回的相對路徑
        encoding: 'base64', //編碼格式
        success: res => { //成功的回調
          wx.cloud.callFunction({
            name:'file',
            data:{
              path: 'pictures/' + util.vcode(new Date())+index+'.png',
              file: res.data
            },
            success(_res){
             
              console.log(_res)
            },fail(_res){
              console.log(_res)
            }
          })
          index++;
        }
      })

 

其中index的作用是對圖片進行區分編碼,有不同的名字,不然重名的文件上傳,原文件會被覆蓋

完整的js文件

import {
  promisify
} from '../../utils/promise.util'
import {
  $init,
  $digest
} from '../../utils/common.util'
var util = require('../../utils/util.js')
const wxUploadFile = promisify(wx.uploadFile)
const db = wx.cloud.database()
Page({

  data: {
    titleCount: 0,
    contentCount: 0,
    content: '',
    images: []
  },

  onLoad(options) {
    $init(this)
  },

  handleTitleInput(e) {
    const value = e.detail.value
    this.data.title = value
    this.data.titleCount = value.length
    $digest(this)
  },

  handleContentInput(e) {
    const value = e.detail.value
    this.data.content = value
    this.data.contentCount = value.length
    $digest(this)
  },
  chooseImage(e) {
    wx.chooseImage({
      count: 3,
      sizeType: ['original', 'compressed'],
      sourceType: ['album', 'camera'],
      success: res => {
        const images = this.data.images.concat(res.tempFilePaths)
        
        this.data.images = images.length <= 3 ? images : images.slice(0, 3)
        $digest(this)
      }
    })
  },

  removeImage(e) {
    const idx = e.target.dataset.idx
    this.data.images.splice(idx, 1)
    $digest(this)
  },

  handleImagePreview(e) {
    const idx = e.target.dataset.idx
    const images = this.data.images

    wx.previewImage({
      current: images[idx],
      urls: images,
    })
  },

  submitForm(e) {
    var that = this;
    var index = 0;
    var len = that.data.images.length;
    wx.showLoading({
      title: '上傳中...',
    })
    for(var i = 0; i < len ; i++)
    {
      console.log(i)
      wx.getFileSystemManager().readFile({
        filePath: that.data.images[i], //選擇圖片返回的相對路徑
        encoding: 'base64', //編碼格式
        success: res => { //成功的回調
          wx.cloud.callFunction({
            name:'file',
            data:{
              path: 'pictures/' + util.vcode(new Date())+index+'.png',
              file: res.data
            },
            success(_res){
             
              console.log(_res)
              wx.hideLoading()
              //wx.hideLoading()
            },fail(_res){
              console.log(_res)
            }
          })
          index++;
        }
      })
    }
  }

})

 

其中 $digest(this) 與 $init(this) 是setData的封裝寫法

詳細內容如下

微信小程序開發工具包--> Gitee

至於想用什么方式保存 返回的文件 id 取決於自己

 

雲函數的寫法

 

// 雲函數入口文件
const cloud = require('wx-server-sdk')
const fs = require('fs')
const path = require('path')
cloud.init({
  env: 'kindear-fd77cd'
})

exports.main = async (event, context) => {
  
  try{
    return await cloud.uploadFile({
      cloudPath: event.path,
      fileContent: new Buffer(event.file, 'base64')
    })
  }catch(e){
    return e;
  }
}

 

其中,必須強調的是cloud.init 必須重新確定下環境id

不然上傳的文件或者圖片並不在小程序初始化的環境中

 

 

雲函數實現效果

 

 

 圖片提交界面如圖所示

點擊提交

 在雲存儲中查看

 

成功上傳

 

 

 

 一種雲存儲文件名稱的編碼方式

基本方式在js文件中已經有具體描述,通過具體到秒的時間 和 圖片的上傳順序進行編碼 基本可以保證不會有重名的文件存在

現在給出時間的編碼方式

function vcode(date)
{
  var year = date.getFullYear()
  var month = date.getMonth() + 1
  var day = date.getDate()

  var hour = date.getHours()
  var minute = date.getMinutes()
  var second = date.getSeconds()

  return [year, month, day].map(formatNumber).join('_')  + '_'+[hour, minute, second].map(formatNumber).join('_')
}

 

 

 

需要小程序開發的請聯系我QQ:1025584691

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM