微信小程序直接上传文件到OSS

1. 封装公共方法

在根目录utils目录新建一个upload文件夹:

// utils/upload/base64.jsvar base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var base64DecodeChars = new Array(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1);
function encode(str) {var out, i, len;var c1, c2, c3;len = str.length;i = 0;out = "";while (i < len) {c1 = str.charCodeAt(i++) & 0xff;if (i == len) {out += base64EncodeChars.charAt(c1 >> 2);out += base64EncodeChars.charAt((c1 & 0x3) << 4);out += "==";break;}c2 = str.charCodeAt(i++);if (i == len) {out += base64EncodeChars.charAt(c1 >> 2);out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));out += base64EncodeChars.charAt((c2 & 0xF) << 2);out += "=";break;}c3 = str.charCodeAt(i++);out += base64EncodeChars.charAt(c1 >> 2);out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));out += base64EncodeChars.charAt(c3 & 0x3F);}return out;
}
function decode(str) {var c1, c2, c3, c4;var i, len, out;len = str.length;i = 0;out = "";while (i < len) {/* c1 */do {c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff];} while (i < len && c1 == -1);if (c1 == -1)break;/* c2 */do {c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff];} while (i < len && c2 == -1);if (c2 == -1)break;out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4));/* c3 */do {c3 = str.charCodeAt(i++) & 0xff;if (c3 == 61)return out;c3 = base64DecodeChars[c3];} while (i < len && c3 == -1);if (c3 == -1)break;out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2));/* c4 */do {c4 = str.charCodeAt(i++) & 0xff;if (c4 == 61)return out;c4 = base64DecodeChars[c4];} while (i < len && c4 == -1);if (c4 == -1)break;out += String.fromCharCode(((c3 & 0x03) << 6) | c4);}return out;
}function utf16to8(str) {var out, i, len, c;out = "";len = str.length;for (i = 0; i < len; i++) {c = str.charCodeAt(i);if ((c >= 0x0001) && (c <= 0x007F)) {out += str.charAt(i);} else if (c > 0x07FF) {out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));} else {out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));}}return out;
}
function utf8to16(str) {var out, i, len, c;var char2, char3;out = "";len = str.length;i = 0;while (i < len) {c = str.charCodeAt(i++);switch (c >> 4) {case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:// 0xxxxxxxout += str.charAt(i - 1);break;case 12: case 13:// 110x xxxx 10xx xxxxchar2 = str.charCodeAt(i++);out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));break;case 14:// 1110 xxxx 10xx xxxx 10xx xxxxchar2 = str.charCodeAt(i++);char3 = str.charCodeAt(i++);out += String.fromCharCode(((c & 0x0F) << 12) |((char2 & 0x3F) << 6) |((char3 & 0x3F) << 0));break;}}return out;
}module.exports = {encode: encode,decode: decode,utf16to8: utf16to8,utf8to16: utf8to16
}
// utils/upload/base64.jsconst Crypto = {};
(function(){var base64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
// Crypto utilities
var util = Crypto.util = {// Bit-wise rotate leftrotl: function (n, b) {return (n << b) | (n >>> (32 - b));},// Bit-wise rotate rightrotr: function (n, b) {return (n << (32 - b)) | (n >>> b);},// Swap big-endian to little-endian and vice versaendian: function (n) {// If number given, swap endianif (n.constructor == Number) {return util.rotl(n,  8) & 0x00FF00FF |util.rotl(n, 24) & 0xFF00FF00;}// Else, assume array and swap all itemsfor (var i = 0; i < n.length; i++)n[i] = util.endian(n[i]);return n;},// Generate an array of any length of random bytesrandomBytes: function (n) {for (var bytes = []; n > 0; n--)bytes.push(Math.floor(Math.random() * 256));return bytes;},// Convert a string to a byte arraystringToBytes: function (str) {var bytes = [];for (var i = 0; i < str.length; i++)bytes.push(str.charCodeAt(i));return bytes;},// Convert a byte array to a stringbytesToString: function (bytes) {var str = [];for (var i = 0; i < bytes.length; i++)str.push(String.fromCharCode(bytes[i]));return str.join("");},// Convert a string to big-endian 32-bit wordsstringToWords: function (str) {var words = [];for (var c = 0, b = 0; c < str.length; c++, b += 8)words[b >>> 5] |= str.charCodeAt(c) << (24 - b % 32);return words;},// Convert a byte array to big-endian 32-bits wordsbytesToWords: function (bytes) {var words = [];for (var i = 0, b = 0; i < bytes.length; i++, b += 8)words[b >>> 5] |= bytes[i] << (24 - b % 32);return words;},// Convert big-endian 32-bit words to a byte arraywordsToBytes: function (words) {var bytes = [];for (var b = 0; b < words.length * 32; b += 8)bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF);return bytes;},// Convert a byte array to a hex stringbytesToHex: function (bytes) {var hex = [];for (var i = 0; i < bytes.length; i++) {hex.push((bytes[i] >>> 4).toString(16));hex.push((bytes[i] & 0xF).toString(16));}return hex.join("");},// Convert a hex string to a byte arrayhexToBytes: function (hex) {var bytes = [];for (var c = 0; c < hex.length; c += 2)bytes.push(parseInt(hex.substr(c, 2), 16));return bytes;},// Convert a byte array to a base-64 stringbytesToBase64: function (bytes) {// Use browser-native function if it existsif (typeof btoa == "function") return btoa(util.bytesToString(bytes));var base64 = [],overflow;for (var i = 0; i < bytes.length; i++) {switch (i % 3) {case 0:base64.push(base64map.charAt(bytes[i] >>> 2));overflow = (bytes[i] & 0x3) << 4;break;case 1:base64.push(base64map.charAt(overflow | (bytes[i] >>> 4)));overflow = (bytes[i] & 0xF) << 2;break;case 2:base64.push(base64map.charAt(overflow | (bytes[i] >>> 6)));base64.push(base64map.charAt(bytes[i] & 0x3F));overflow = -1;}}// Encode overflow bits, if there are anyif (overflow != undefined && overflow != -1)base64.push(base64map.charAt(overflow));// Add paddingwhile (base64.length % 4 != 0) base64.push("=");return base64.join("");},// Convert a base-64 string to a byte arraybase64ToBytes: function (base64) {// Use browser-native function if it existsif (typeof atob == "function") return util.stringToBytes(atob(base64));// Remove non-base-64 charactersbase64 = base64.replace(/[^A-Z0-9+\/]/ig, "");var bytes = [];for (var i = 0; i < base64.length; i++) {switch (i % 4) {case 1:bytes.push((base64map.indexOf(base64.charAt(i - 1)) << 2) |(base64map.indexOf(base64.charAt(i)) >>> 4));break;case 2:bytes.push(((base64map.indexOf(base64.charAt(i - 1)) & 0xF) << 4) |(base64map.indexOf(base64.charAt(i)) >>> 2));break;case 3:bytes.push(((base64map.indexOf(base64.charAt(i - 1)) & 0x3) << 6) |(base64map.indexOf(base64.charAt(i))));break;}}return bytes;}
};// Crypto mode namespace
Crypto.mode = {};
})();
module.exports = Crypto;
// utils/upload/hmac.jsconst Crypto = require('./crypto.js');
(function(){// Shortcut
var util = Crypto.util;
Crypto.HMAC = function (hasher, message, key, options) {// Allow arbitrary length keyskey = key.length > hasher._blocksize * 4 ?hasher(key, { asBytes: true }) :util.stringToBytes(key);// XOR keys with pad constantsvar okey = key,ikey = key.slice(0);for (var i = 0; i < hasher._blocksize * 4; i++) {okey[i] ^= 0x5C;ikey[i] ^= 0x36;}var hmacbytes = hasher(util.bytesToString(okey) +hasher(util.bytesToString(ikey) + message, { asString: true }),{ asBytes: true });return options && options.asBytes ? hmacbytes :options && options.asString ? util.bytesToString(hmacbytes) :util.bytesToHex(hmacbytes);
};
})();module.exports = Crypto;
// utils/upload/sha1.jsconst Crypto = require('./crypto.js');
(function(){// Shortcut
var util = Crypto.util;
// Public API
var SHA1 = Crypto.SHA1 = function (message, options) {var digestbytes = util.wordsToBytes(SHA1._sha1(message));return options && options.asBytes ? digestbytes :options && options.asString ? util.bytesToString(digestbytes) :util.bytesToHex(digestbytes);
};
// The core
SHA1._sha1 = function (message) {var m  = util.stringToWords(message),l  = message.length * 8,w  =  [],H0 =  1732584193,H1 = -271733879,H2 = -1732584194,H3 =  271733878,H4 = -1009589776;// Paddingm[l >> 5] |= 0x80 << (24 - l % 32);m[((l + 64 >>> 9) << 4) + 15] = l;for (var i = 0; i < m.length; i += 16) {var a = H0,b = H1,c = H2,d = H3,e = H4;for (var j = 0; j < 80; j++) {if (j < 16) w[j] = m[i + j];else {var n = w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16];w[j] = (n << 1) | (n >>> 31);}var t = ((H0 << 5) | (H0 >>> 27)) + H4 + (w[j] >>> 0) + (j < 20 ? (H1 & H2 | ~H1 & H3) + 1518500249 :j < 40 ? (H1 ^ H2 ^ H3) + 1859775393 :j < 60 ? (H1 & H2 | H1 & H3 | H2 & H3) - 1894007588 :(H1 ^ H2 ^ H3) - 899497514);H4 =  H3;H3 =  H2;H2 = (H1 << 30) | (H1 >>> 2);H1 =  H0;H0 =  t;}H0 += a;H1 += b;H2 += c;H3 += d;H4 += e;}return [H0, H1, H2, H3, H4];
};
// Package private blocksize
SHA1._blocksize = 16;
})();module.exports = Crypto;

以上基础库可以使用第三方库来实现。

// utils/upload/uploadFile.jsimport { ossConfig } from '../../config/index'  //配置文件
const base64 = require('base64.js');//Base64,hmac,sha1,crypto相关算法
require('hmac.js');
require('sha1.js');
const Crypto = require('crypto.js');/**上传文件到阿里云oss*@param - filePath :图片的本地资源路径*@param - dir:表示要传到哪个目录下*@param - successc:成功回调*@param - failc:失败回调*/
const uploadFile = function (filePath, dir, successc, failc) {if (!filePath || filePath.length < 9) {wx.showModal({title: '图片错误',content: '请重试',showCancel: false,})return;}//图片名字 可以自行定义,这里是采用当前的时间戳 + 150内的随机数来给图片命名的const aliyunFileKey = dir+ new Date().getTime() + Math.floor(Math.random() * 150) + '.png';const aliyunServerURL = ossConfig.bucketUrl; //OSS地址,需要https  uploadImageUrlconst accessid = ossConfig.accessKeyId;const policyBase64 = getPolicyBase64();const signature = getSignature(policyBase64);//获取签名return new Promise((resolve, reject) => {wx.uploadFile({url: aliyunServerURL,//开发者服务器 urlfilePath: filePath,//要上传文件资源的路径name: 'file',//必须填fileformData: {'key': aliyunFileKey,'policy': policyBase64,'OSSAccessKeyId': accessid,'signature': signature,'success_action_status': '200',},success: function (res) {if (res.statusCode != 200) {failc(new Error('上传错误:' + JSON.stringify(res)))return;}successc(aliyunServerURL+"/"+aliyunFileKey);resolve(aliyunServerURL+"/"+aliyunFileKey)},fail: function (err) {err.wxaddinfo = aliyunServerURL;failc(err);reject(err)},})})
}const getPolicyBase64 = function () {let date = new Date();date.setHours(date.getHours() + ossConfig.timeout);let srcT = date.toISOString();const policyText = {"expiration": srcT, //设置该Policy的失效时间,超过这个失效时间之后,就没有办法通过这个policy上传文件了 "conditions": [["content-length-range", 0, 5 * 1024 * 1024] // 设置上传文件的大小限制,5mb]};const policyBase64 = base64.encode(JSON.stringify(policyText));return policyBase64;
}const getSignature = function (policyBase64) {const accesskey = ossConfig.accessKeySecret;const bytes = Crypto.HMAC(Crypto.SHA1, policyBase64, accesskey, {asBytes: true});const signature = Crypto.util.bytesToBase64(bytes);return signature;
}module.exports = uploadFile;

以上文件中用到OSS 配置文件:

// config/index.jsexport const ossConfig = {bucketUrl: "https://bucker-****-****.oss-cn-shenzhen.aliyuncs.com",accessKeyId: "LTAI5t*********Yggx",accessKeySecret: "6yH2fdn******2aFrDqbqiPD7",regionId: "cn-shenzhen",timeout: 80000,dirPrefix: "test/headImage/"  // 保存文件路径前缀
}

2. 上传头像

<!--pages/order/order.wxml-->
<view style="margin-top: 100rpx;text-align: center;">上传头像</view>
<button class="avatar-wrapper" open-type="chooseAvatar" bind:chooseavatar="onChooseAvatar"><image class="avatar" src="{{ logo ? logo : '' }}"></image>
</button>
<button type="primary" bindtap="onSubmit">确认上传</button>
// pages/order/order.js
import { ossConfig } from '../../config/index'
const upload = require('../../utils/upload/uploadFile')
Page({data: {logo: ''},onShow() {this.getTabBar().init()},async uploadImage(path){ // 上传文件到OSSconst _self = this;wx.showLoading({title: '上传中',mask: true})var nowTime = new Date();let parseDate = "" + nowTime.getFullYear() + (nowTime.getMonth()+1 < 10 ? ('0'+nowTime.getMonth()+1) : (nowTime.getMonth()+1)) + (nowTime.getDay() < 10 ? ('0'+nowTime.getDay()) : nowTime.getDay())return upload(path, ossConfig.dirPrefix + parseDate + '/',function (result) {_self.setData({logo: result})wx.hideLoading();}, function (err) {wx.hideLoading();wx.showToast({title: '上传失败',icon: 'none'})})},onChooseAvatar(e) { // 选择图片预览const { avatarUrl } = e.detail this.setData({logo: avatarUrl})},async onSubmit(){// 上传图片if(this.data.logo.indexOf("//tmp") > -1){await this.uploadImage(this.data.logo)}console.log(this.data.logo)  // OSS 上传文件路径}
})
/* pages/order/order.wxss */
.avatar-wrapper {padding: 0;width: 100rpx !important;height: 100rpx !important;border-radius: 50%;border: none !important;background-color: #ccc;display: block;margin: 50rpx auto;
}
.avatar-wrapper .avatar {display: inline;width: 100rpx;height: 100rpx;
}

实现效果:

注意:需要小程序后台配置服务器域名,将阿里云OSS地址加入request合法域名、配置uploadFile合法域名、downloadFile合法域名。如:https://bucker-****-****.oss-cn-shenzhen.aliyuncs.com

头像昵称填写,从基础库 2.21.2 开始支持,当小程序需要让用户完善个人资料时,可以通过微信提供的头像昵称填写能力快速完善。

根据相关法律法规,为确保信息安全,由用户上传的图片、昵称等信息微信侧将进行安全检测,组件从基础库2.24.4版本起,已接入内容安全服务端接口(mediaCheckAsync、msgSecCheck),以减少内容安全风险对开发者的影响。
官方文档:开放能力/用户信息/获取头像昵称

微信小程序直接上传文件到阿里云OSS组件封装相关推荐

  1. 【微信小程序】上传文件到阿里云OSS

    小程序上传文件到OSS也是利用OSS提供的PostObject接口来实现表单文件上传到OSS 步骤1:配置Bucket跨域访问 客户端进行表单直传到OSS时,会从浏览器向OSS发送带有Origin的请 ...

  2. [server]基于uniapp创建小程序并上传照片到阿里云OSS

    先说在前头,最近忙,随想随记,所以有些博客写了一半就发了,后续会慢慢补齐的.抱歉! 前端使用uniapp开发,后台挂在阿里云.选uniapp开发的原因是我这边人手不够,同时也不想维护这么多客户端,故选 ...

  3. java上传文件至阿里云oss工具类

    第一步:引入oss maven坐标 <dependency><groupId>com.aliyun.oss</groupId><artifactId>a ...

  4. 微信小程序实现上传文件 如图片/word excel到服务器

    说道上传文件,首先要想到微信官方文档给的API,wx.uploadFile({ }) 通过这个API来达到上传至服务器的效果:代码示例如下 接下来我们先来说说上传图片功能,这个比较简单一些 上传图片: ...

  5. 微信小程序 Vant 上传文件

    上传附件 使用van-uploader组件 <van-uploader file-list="{{ fileList }}" bind:after-read="af ...

  6. 小程序上传文件到阿里云oss

    本文仅举例上传图片和上传视频! 准备工作: 需要引入的js文件:https://download.csdn.net/download/impossible1994727/12328614 参考文档:h ...

  7. go walk 开发window界面,上传文件到阿里云oss -- 服务器端

    前面我们完成了一个网页端的上传oss程序:https://blog.csdn.net/daily886/article/details/103366145 现在我们把前后端分离 前端使用walk开发, ...

  8. go 使用 gin 上传文件到 阿里云oss存储

    本文使用 go 版本是: go version go1.13 linux/amd64 阿里云oss go sdk版本:v2.0.4  官网可以下载 linux版本是:Linux version 3.1 ...

  9. vue 上传文件至阿里云oss

    先让后端在阿里云里面处理跨域问题 参考这篇文章   vue直传图片到阿里云OSS(单张直接上传)__小郑有点困了的博客-CSDN博客_vue 阿里云背景:近期项目使用到多图片上传功能,常规的调用后端接 ...

最新文章

  1. 图神经网络综述:方法及应用 | Deep Reading
  2. HDU 2149 Public Sale
  3. 计算机的登入灯出操作系统,为什么计算机不能像电灯一样瞬时打开?
  4. cesium three性能比较_mapboxgl + three 动画 — 网格热图
  5. python ---单例(Singleton)
  6. PLSQL Developer 64位下载
  7. 可以免费下载任何文档(网页转换助手)
  8. 专家称米粒倒闭是个案 不必大惊小怪
  9. mysql完整性实验报告_MySQL数据库技术实验报告模板
  10. 驱动精灵w8ndows xp sp2,惠普打印机驱动官方正式版下载,适用于winxp,win2003,winvista,win7,win8,win10,win2008,win2012-驱动精灵...
  11. 3D线激光成像数学模型简析与实现
  12. 光谱数据计算色彩指标的软件(功能强大,齐全)
  13. CRMEB小程序商城v4.0二次开发对接集成阿里云短信
  14. 风格化(Stylization)
  15. Access key id should not be null or empty.
  16. C语言decompose函数,R语言时间序列应用(decompose、Holt-Winters初步)
  17. 亚马逊FBA标签打印技巧(深圳风火轮amazon团队)
  18. acwing——数学知识(四)Nim游戏
  19. PADS(二)更多使用和实战总结
  20. 动态生成验证码+验证码的校验

热门文章

  1. mysql单表瓶颈_mysql单表性能瓶颈_优化系列 | 实例解析MySQL性能瓶颈排查定位-云栖社区-阿里云...
  2. bootstrap fileupload 使用详解~~
  3. 触发器-- 肖敏_入门系列_数据库进阶 60、触发器(三) --youku
  4. XYplorer使用教程
  5. 1、Mac如何剪切文件
  6. fabric8镜像的deployments脚本
  7. 密码技术的典型应用——电子印章
  8. PetaLiunx配置时sourcing bitbake报错解决方法
  9. Mysql数据库操作语句总结(一)
  10. 阿卡迪亚大学计算机专业好考吗,申请阿卡迪亚大学究竟难不难?