├── .gitignore
├── LICENSE
├── README.md
├── app.js
├── app.json
├── app.wxss
├── pages
├── index
│ ├── index.js
│ ├── index.wxml
│ └── index.wxss
└── logs
│ ├── logs.js
│ ├── logs.json
│ ├── logs.wxml
│ └── logs.wxss
├── project.config.json
└── utils
├── base64.js
├── config.js
├── crypto.js
├── hmac.js
├── sha1.js
├── uploadFile.js
└── util.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 |
5 | # Files for the ART/Dalvik VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # Generated files
12 | bin/
13 | gen/
14 | out/
15 |
16 | # Gradle files
17 | .gradle/
18 | build/
19 |
20 | # Local configuration file (sdk path, etc)
21 | local.properties
22 |
23 | # Proguard folder generated by Eclipse
24 | proguard/
25 |
26 | # Log Files
27 | *.log
28 |
29 | # Android Studio Navigation editor temp files
30 | .navigation/
31 |
32 | # Android Studio captures folder
33 | captures/
34 |
35 | # IntelliJ
36 | *.iml
37 | .idea/workspace.xml
38 | .idea/tasks.xml
39 | .idea/gradle.xml
40 | .idea/assetWizardSettings.xml
41 | .idea/dictionaries
42 | .idea/libraries
43 | .idea/caches
44 |
45 | # Keystore files
46 | # Uncomment the following line if you do not want to check your keystore files in.
47 | #*.jks
48 |
49 | # External native build folder generated in Android Studio 2.2 and later
50 | .externalNativeBuild
51 |
52 | # Google Services (e.g. APIs or Firebase)
53 | google-services.json
54 |
55 | # Freeline
56 | freeline.py
57 | freeline/
58 | freeline_project_description.json
59 |
60 | # fastlane
61 | fastlane/report.xml
62 | fastlane/Preview.html
63 | fastlane/screenshots
64 | fastlane/test_output
65 | fastlane/readme.md
66 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Image_upload_aliyun
2 | 微信小程序上传图片到阿里云oss
3 |
4 | 我把主要注释都写在js文件里了,相信你们都看的懂哈!!!
5 |
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
1 | //app.js
2 | App({
3 | onLaunch: function () {
4 | // 展示本地存储能力
5 | var logs = wx.getStorageSync('logs') || []
6 | logs.unshift(Date.now())
7 | wx.setStorageSync('logs', logs)
8 |
9 | // 登录
10 | wx.login({
11 | success: res => {
12 | // 发送 res.code 到后台换取 openId, sessionKey, unionId
13 | }
14 | })
15 | // 获取用户信息
16 | wx.getSetting({
17 | success: res => {
18 | if (res.authSetting['scope.userInfo']) {
19 | // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
20 | wx.getUserInfo({
21 | success: res => {
22 | // 可以将 res 发送给后台解码出 unionId
23 | this.globalData.userInfo = res.userInfo
24 |
25 | // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
26 | // 所以此处加入 callback 以防止这种情况
27 | if (this.userInfoReadyCallback) {
28 | this.userInfoReadyCallback(res)
29 | }
30 | }
31 | })
32 | }
33 | }
34 | })
35 | },
36 | globalData: {
37 | userInfo: null
38 | }
39 | })
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "pages":[
3 | "pages/index/index",
4 | "pages/logs/logs"
5 | ],
6 | "window":{
7 | "backgroundTextStyle":"light",
8 | "navigationBarBackgroundColor": "#fff",
9 | "navigationBarTitleText": "WeChat",
10 | "navigationBarTextStyle":"black"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/app.wxss:
--------------------------------------------------------------------------------
1 | /**app.wxss**/
2 | .container {
3 | height: 100%;
4 | display: flex;
5 | flex-direction: column;
6 | align-items: center;
7 | justify-content: space-between;
8 | padding: 200rpx 0;
9 | box-sizing: border-box;
10 | }
11 |
--------------------------------------------------------------------------------
/pages/index/index.js:
--------------------------------------------------------------------------------
1 | //index.js
2 | //获取应用实例
3 | const app = getApp()
4 | var uploadImage = require('../../utils/uploadFile.js');
5 | var util = require('../../utils/util.js');
6 |
7 | Page({
8 | data: {
9 |
10 | },
11 |
12 | //选择照片
13 | choose:function(){
14 | wx.chooseImage({
15 | count: 9, // 默认最多一次选择9张图
16 | sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
17 | sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
18 | success: function (res) {
19 | // 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
20 | var tempFilePaths = res.tempFilePaths;
21 | var nowTime = util.formatTime(new Date());
22 |
23 | //支持多图上传
24 | for (var i = 0; i < res.tempFilePaths.length; i++) {
25 | //显示消息提示框
26 | wx.showLoading({
27 | title: '上传中' + (i + 1) + '/' + res.tempFilePaths.length,
28 | mask: true
29 | })
30 |
31 | //上传图片
32 | //你的域名下的/cbb文件下的/当前年月日文件下的/图片.png
33 | //图片路径可自行修改
34 | uploadImage(res.tempFilePaths[i], 'cbb/' + nowTime + '/',
35 | function (result) {
36 | console.log("======上传成功图片地址为:", result);
37 | wx.hideLoading();
38 | }, function (result) {
39 | console.log("======上传失败======", result);
40 | wx.hideLoading()
41 | }
42 | )
43 | }
44 | }
45 | })
46 | }
47 | })
48 |
--------------------------------------------------------------------------------
/pages/index/index.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/pages/index/index.wxss:
--------------------------------------------------------------------------------
1 | /**index.wxss**/
2 | .userinfo {
3 | display: flex;
4 | flex-direction: column;
5 | align-items: center;
6 | }
7 |
8 | .userinfo-avatar {
9 | width: 128rpx;
10 | height: 128rpx;
11 | margin: 20rpx;
12 | border-radius: 50%;
13 | }
14 |
15 | .userinfo-nickname {
16 | color: #aaa;
17 | }
18 |
19 | .usermotto {
20 | margin-top: 200px;
21 | }
--------------------------------------------------------------------------------
/pages/logs/logs.js:
--------------------------------------------------------------------------------
1 | //logs.js
2 | const util = require('../../utils/util.js')
3 |
4 | Page({
5 | data: {
6 | logs: []
7 | },
8 | onLoad: function () {
9 | this.setData({
10 | logs: (wx.getStorageSync('logs') || []).map(log => {
11 | return util.formatTime(new Date(log))
12 | })
13 | })
14 | }
15 | })
16 |
--------------------------------------------------------------------------------
/pages/logs/logs.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "查看启动日志"
3 | }
--------------------------------------------------------------------------------
/pages/logs/logs.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{index + 1}}. {{log}}
5 |
6 |
7 |
--------------------------------------------------------------------------------
/pages/logs/logs.wxss:
--------------------------------------------------------------------------------
1 | .log-list {
2 | display: flex;
3 | flex-direction: column;
4 | padding: 40rpx;
5 | }
6 | .log-item {
7 | margin: 10rpx;
8 | }
9 |
--------------------------------------------------------------------------------
/project.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "description": "项目配置文件。",
3 | "packOptions": {
4 | "ignore": []
5 | },
6 | "setting": {
7 | "urlCheck": false,
8 | "es6": true,
9 | "postcss": true,
10 | "minified": true,
11 | "newFeature": true
12 | },
13 | "compileType": "miniprogram",
14 | "libVersion": "2.2.1",
15 | "appid": "wxd746238ccb61936d",
16 | "projectname": "11",
17 | "isGameTourist": false,
18 | "condition": {
19 | "search": {
20 | "current": -1,
21 | "list": []
22 | },
23 | "conversation": {
24 | "current": -1,
25 | "list": []
26 | },
27 | "game": {
28 | "currentL": -1,
29 | "list": []
30 | },
31 | "miniprogram": {
32 | "current": -1,
33 | "list": []
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/utils/base64.js:
--------------------------------------------------------------------------------
1 |
2 | var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
3 | var base64DecodeChars = new Array(
4 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
5 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
6 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
7 | 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
8 | -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
9 | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
10 | -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
11 | 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1);
12 | function encode(str) {
13 | var out, i, len;
14 | var c1, c2, c3;
15 | len = str.length;
16 | i = 0;
17 | out = "";
18 | while (i < len) {
19 | c1 = str.charCodeAt(i++) & 0xff;
20 | if (i == len) {
21 | out += base64EncodeChars.charAt(c1 >> 2);
22 | out += base64EncodeChars.charAt((c1 & 0x3) << 4);
23 | out += "==";
24 | break;
25 | }
26 | c2 = str.charCodeAt(i++);
27 | if (i == len) {
28 | out += base64EncodeChars.charAt(c1 >> 2);
29 | out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
30 | out += base64EncodeChars.charAt((c2 & 0xF) << 2);
31 | out += "=";
32 | break;
33 | }
34 | c3 = str.charCodeAt(i++);
35 | out += base64EncodeChars.charAt(c1 >> 2);
36 | out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
37 | out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
38 | out += base64EncodeChars.charAt(c3 & 0x3F);
39 | }
40 | return out;
41 | }
42 | function decode(str) {
43 | var c1, c2, c3, c4;
44 | var i, len, out;
45 | len = str.length;
46 | i = 0;
47 | out = "";
48 | while (i < len) {
49 | /* c1 */
50 | do {
51 | c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
52 | } while (i < len && c1 == -1);
53 | if (c1 == -1)
54 | break;
55 | /* c2 */
56 | do {
57 | c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
58 | } while (i < len && c2 == -1);
59 | if (c2 == -1)
60 | break;
61 | out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4));
62 | /* c3 */
63 | do {
64 | c3 = str.charCodeAt(i++) & 0xff;
65 | if (c3 == 61)
66 | return out;
67 | c3 = base64DecodeChars[c3];
68 | } while (i < len && c3 == -1);
69 | if (c3 == -1)
70 | break;
71 | out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2));
72 | /* c4 */
73 | do {
74 | c4 = str.charCodeAt(i++) & 0xff;
75 | if (c4 == 61)
76 | return out;
77 | c4 = base64DecodeChars[c4];
78 | } while (i < len && c4 == -1);
79 | if (c4 == -1)
80 | break;
81 | out += String.fromCharCode(((c3 & 0x03) << 6) | c4);
82 | }
83 | return out;
84 | }
85 |
86 |
87 | function utf16to8(str) {
88 | var out, i, len, c;
89 | out = "";
90 | len = str.length;
91 | for (i = 0; i < len; i++) {
92 | c = str.charCodeAt(i);
93 | if ((c >= 0x0001) && (c <= 0x007F)) {
94 | out += str.charAt(i);
95 | } else if (c > 0x07FF) {
96 | out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
97 | out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
98 | out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
99 | } else {
100 | out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
101 | out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
102 | }
103 | }
104 | return out;
105 | }
106 | function utf8to16(str) {
107 | var out, i, len, c;
108 | var char2, char3;
109 | out = "";
110 | len = str.length;
111 | i = 0;
112 | while (i < len) {
113 | c = str.charCodeAt(i++);
114 | switch (c >> 4) {
115 | case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
116 | // 0xxxxxxx
117 | out += str.charAt(i - 1);
118 | break;
119 | case 12: case 13:
120 | // 110x xxxx 10xx xxxx
121 | char2 = str.charCodeAt(i++);
122 | out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
123 | break;
124 | case 14:
125 | // 1110 xxxx 10xx xxxx 10xx xxxx
126 | char2 = str.charCodeAt(i++);
127 | char3 = str.charCodeAt(i++);
128 | out += String.fromCharCode(((c & 0x0F) << 12) |
129 | ((char2 & 0x3F) << 6) |
130 | ((char3 & 0x3F) << 0));
131 | break;
132 | }
133 | }
134 | return out;
135 | }
136 |
137 |
138 | module.exports = {
139 | encode: encode,
140 | decode: decode,
141 | utf16to8: utf16to8,
142 | utf8to16: utf8to16
143 | }
--------------------------------------------------------------------------------
/utils/config.js:
--------------------------------------------------------------------------------
1 | var fileHost = "https://xxx/";//你的阿里云地址最后面跟上一个/ 在你当前小程序的后台的uploadFile 合法域名也要配上这个域名
2 | var config = {
3 | //aliyun OSS config
4 | uploadImageUrl: `${fileHost}`, // 默认存在根目录,可根据需求改
5 | AccessKeySecret: 'xxx', // AccessKeySecret 去你的阿里云上控制台上找
6 | OSSAccessKeyId: 'xxx', // AccessKeyId 去你的阿里云上控制台上找
7 | timeout: 87600 //这个是上传文件时Policy的失效时间
8 | };
9 | module.exports = config
--------------------------------------------------------------------------------
/utils/crypto.js:
--------------------------------------------------------------------------------
1 | const Crypto = {};
2 |
3 | (function(){
4 |
5 | var base64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
6 |
7 |
8 | // Crypto utilities
9 | var util = Crypto.util = {
10 |
11 | // Bit-wise rotate left
12 | rotl: function (n, b) {
13 | return (n << b) | (n >>> (32 - b));
14 | },
15 |
16 | // Bit-wise rotate right
17 | rotr: function (n, b) {
18 | return (n << (32 - b)) | (n >>> b);
19 | },
20 |
21 | // Swap big-endian to little-endian and vice versa
22 | endian: function (n) {
23 |
24 | // If number given, swap endian
25 | if (n.constructor == Number) {
26 | return util.rotl(n, 8) & 0x00FF00FF |
27 | util.rotl(n, 24) & 0xFF00FF00;
28 | }
29 |
30 | // Else, assume array and swap all items
31 | for (var i = 0; i < n.length; i++)
32 | n[i] = util.endian(n[i]);
33 | return n;
34 |
35 | },
36 |
37 | // Generate an array of any length of random bytes
38 | randomBytes: function (n) {
39 | for (var bytes = []; n > 0; n--)
40 | bytes.push(Math.floor(Math.random() * 256));
41 | return bytes;
42 | },
43 |
44 | // Convert a string to a byte array
45 | stringToBytes: function (str) {
46 | var bytes = [];
47 | for (var i = 0; i < str.length; i++)
48 | bytes.push(str.charCodeAt(i));
49 | return bytes;
50 | },
51 |
52 | // Convert a byte array to a string
53 | bytesToString: function (bytes) {
54 | var str = [];
55 | for (var i = 0; i < bytes.length; i++)
56 | str.push(String.fromCharCode(bytes[i]));
57 | return str.join("");
58 | },
59 |
60 | // Convert a string to big-endian 32-bit words
61 | stringToWords: function (str) {
62 | var words = [];
63 | for (var c = 0, b = 0; c < str.length; c++, b += 8)
64 | words[b >>> 5] |= str.charCodeAt(c) << (24 - b % 32);
65 | return words;
66 | },
67 |
68 | // Convert a byte array to big-endian 32-bits words
69 | bytesToWords: function (bytes) {
70 | var words = [];
71 | for (var i = 0, b = 0; i < bytes.length; i++, b += 8)
72 | words[b >>> 5] |= bytes[i] << (24 - b % 32);
73 | return words;
74 | },
75 |
76 | // Convert big-endian 32-bit words to a byte array
77 | wordsToBytes: function (words) {
78 | var bytes = [];
79 | for (var b = 0; b < words.length * 32; b += 8)
80 | bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF);
81 | return bytes;
82 | },
83 |
84 | // Convert a byte array to a hex string
85 | bytesToHex: function (bytes) {
86 | var hex = [];
87 | for (var i = 0; i < bytes.length; i++) {
88 | hex.push((bytes[i] >>> 4).toString(16));
89 | hex.push((bytes[i] & 0xF).toString(16));
90 | }
91 | return hex.join("");
92 | },
93 |
94 | // Convert a hex string to a byte array
95 | hexToBytes: function (hex) {
96 | var bytes = [];
97 | for (var c = 0; c < hex.length; c += 2)
98 | bytes.push(parseInt(hex.substr(c, 2), 16));
99 | return bytes;
100 | },
101 |
102 | // Convert a byte array to a base-64 string
103 | bytesToBase64: function (bytes) {
104 |
105 | // Use browser-native function if it exists
106 | if (typeof btoa == "function") return btoa(util.bytesToString(bytes));
107 |
108 | var base64 = [],
109 | overflow;
110 |
111 | for (var i = 0; i < bytes.length; i++) {
112 | switch (i % 3) {
113 | case 0:
114 | base64.push(base64map.charAt(bytes[i] >>> 2));
115 | overflow = (bytes[i] & 0x3) << 4;
116 | break;
117 | case 1:
118 | base64.push(base64map.charAt(overflow | (bytes[i] >>> 4)));
119 | overflow = (bytes[i] & 0xF) << 2;
120 | break;
121 | case 2:
122 | base64.push(base64map.charAt(overflow | (bytes[i] >>> 6)));
123 | base64.push(base64map.charAt(bytes[i] & 0x3F));
124 | overflow = -1;
125 | }
126 | }
127 |
128 | // Encode overflow bits, if there are any
129 | if (overflow != undefined && overflow != -1)
130 | base64.push(base64map.charAt(overflow));
131 |
132 | // Add padding
133 | while (base64.length % 4 != 0) base64.push("=");
134 |
135 | return base64.join("");
136 |
137 | },
138 |
139 | // Convert a base-64 string to a byte array
140 | base64ToBytes: function (base64) {
141 |
142 | // Use browser-native function if it exists
143 | if (typeof atob == "function") return util.stringToBytes(atob(base64));
144 |
145 | // Remove non-base-64 characters
146 | base64 = base64.replace(/[^A-Z0-9+\/]/ig, "");
147 |
148 | var bytes = [];
149 |
150 | for (var i = 0; i < base64.length; i++) {
151 | switch (i % 4) {
152 | case 1:
153 | bytes.push((base64map.indexOf(base64.charAt(i - 1)) << 2) |
154 | (base64map.indexOf(base64.charAt(i)) >>> 4));
155 | break;
156 | case 2:
157 | bytes.push(((base64map.indexOf(base64.charAt(i - 1)) & 0xF) << 4) |
158 | (base64map.indexOf(base64.charAt(i)) >>> 2));
159 | break;
160 | case 3:
161 | bytes.push(((base64map.indexOf(base64.charAt(i - 1)) & 0x3) << 6) |
162 | (base64map.indexOf(base64.charAt(i))));
163 | break;
164 | }
165 | }
166 |
167 | return bytes;
168 |
169 | }
170 |
171 | };
172 |
173 | // Crypto mode namespace
174 | Crypto.mode = {};
175 |
176 | })();
177 |
178 | module.exports = Crypto;
--------------------------------------------------------------------------------
/utils/hmac.js:
--------------------------------------------------------------------------------
1 | const Crypto = require('./crypto.js');
2 |
3 | (function(){
4 |
5 | // Shortcut
6 | var util = Crypto.util;
7 |
8 | Crypto.HMAC = function (hasher, message, key, options) {
9 |
10 | // Allow arbitrary length keys
11 | key = key.length > hasher._blocksize * 4 ?
12 | hasher(key, { asBytes: true }) :
13 | util.stringToBytes(key);
14 |
15 | // XOR keys with pad constants
16 | var okey = key,
17 | ikey = key.slice(0);
18 | for (var i = 0; i < hasher._blocksize * 4; i++) {
19 | okey[i] ^= 0x5C;
20 | ikey[i] ^= 0x36;
21 | }
22 |
23 | var hmacbytes = hasher(util.bytesToString(okey) +
24 | hasher(util.bytesToString(ikey) + message, { asString: true }),
25 | { asBytes: true });
26 | return options && options.asBytes ? hmacbytes :
27 | options && options.asString ? util.bytesToString(hmacbytes) :
28 | util.bytesToHex(hmacbytes);
29 |
30 | };
31 |
32 | })();
33 |
34 | module.exports = Crypto;
--------------------------------------------------------------------------------
/utils/sha1.js:
--------------------------------------------------------------------------------
1 | const Crypto = require('./crypto.js');
2 |
3 | (function(){
4 |
5 | // Shortcut
6 | var util = Crypto.util;
7 |
8 | // Public API
9 | var SHA1 = Crypto.SHA1 = function (message, options) {
10 | var digestbytes = util.wordsToBytes(SHA1._sha1(message));
11 | return options && options.asBytes ? digestbytes :
12 | options && options.asString ? util.bytesToString(digestbytes) :
13 | util.bytesToHex(digestbytes);
14 | };
15 |
16 | // The core
17 | SHA1._sha1 = function (message) {
18 |
19 | var m = util.stringToWords(message),
20 | l = message.length * 8,
21 | w = [],
22 | H0 = 1732584193,
23 | H1 = -271733879,
24 | H2 = -1732584194,
25 | H3 = 271733878,
26 | H4 = -1009589776;
27 |
28 | // Padding
29 | m[l >> 5] |= 0x80 << (24 - l % 32);
30 | m[((l + 64 >>> 9) << 4) + 15] = l;
31 |
32 | for (var i = 0; i < m.length; i += 16) {
33 |
34 | var a = H0,
35 | b = H1,
36 | c = H2,
37 | d = H3,
38 | e = H4;
39 |
40 | for (var j = 0; j < 80; j++) {
41 |
42 | if (j < 16) w[j] = m[i + j];
43 | else {
44 | var n = w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16];
45 | w[j] = (n << 1) | (n >>> 31);
46 | }
47 |
48 | var t = ((H0 << 5) | (H0 >>> 27)) + H4 + (w[j] >>> 0) + (
49 | j < 20 ? (H1 & H2 | ~H1 & H3) + 1518500249 :
50 | j < 40 ? (H1 ^ H2 ^ H3) + 1859775393 :
51 | j < 60 ? (H1 & H2 | H1 & H3 | H2 & H3) - 1894007588 :
52 | (H1 ^ H2 ^ H3) - 899497514);
53 |
54 | H4 = H3;
55 | H3 = H2;
56 | H2 = (H1 << 30) | (H1 >>> 2);
57 | H1 = H0;
58 | H0 = t;
59 |
60 | }
61 |
62 | H0 += a;
63 | H1 += b;
64 | H2 += c;
65 | H3 += d;
66 | H4 += e;
67 |
68 | }
69 |
70 | return [H0, H1, H2, H3, H4];
71 |
72 | };
73 |
74 | // Package private blocksize
75 | SHA1._blocksize = 16;
76 |
77 | })();
78 |
79 | module.exports = Crypto;
--------------------------------------------------------------------------------
/utils/uploadFile.js:
--------------------------------------------------------------------------------
1 | const env = require('config.js'); //配置文件,在这文件里配置你的OSS keyId和KeySecret,timeout:87600;
2 |
3 | const base64 = require('base64.js');//Base64,hmac,sha1,crypto相关算法
4 | require('hmac.js');
5 | require('sha1.js');
6 | const Crypto = require('crypto.js');
7 |
8 | /*
9 | *上传文件到阿里云oss
10 | *@param - filePath :图片的本地资源路径
11 | *@param - dir:表示要传到哪个目录下
12 | *@param - successc:成功回调
13 | *@param - failc:失败回调
14 | */
15 | const uploadFile = function (filePath, dir, successc, failc) {
16 | if (!filePath || filePath.length < 9) {
17 | wx.showModal({
18 | title: '图片错误',
19 | content: '请重试',
20 | showCancel: false,
21 | })
22 | return;
23 | }
24 |
25 | console.log('上传图片.....');
26 |
27 | // 获取上传的文件类型
28 | let fileTypeIndex = filePath.lastIndexOf('.');
29 | let fileType = filePath.substring(fileTypeIndex);
30 |
31 | //图片名字 可以自行定义, 这里是采用当前的时间戳 + 150内的随机数来给图片命名的
32 | // const aliyunFileKey = dir + new Date().getTime() + Math.floor(Math.random() * 150) + '.png';
33 | const aliyunFileKey = dir + new Date().getTime() + Math.floor(Math.random() * 150) + fileType;
34 |
35 | const aliyunServerURL = env.uploadImageUrl;//OSS地址,需要https
36 | const accessid = env.OSSAccessKeyId;
37 | const policyBase64 = getPolicyBase64();
38 | const signature = getSignature(policyBase64);//获取签名
39 |
40 | wx.uploadFile({
41 | url: aliyunServerURL,//开发者服务器 url
42 | filePath: filePath,//要上传文件资源的路径
43 | name: 'file',//必须填file
44 | formData: {
45 | 'key': aliyunFileKey,
46 | 'policy': policyBase64,
47 | 'OSSAccessKeyId': accessid,
48 | 'signature': signature,
49 | 'success_action_status': '200',
50 | },
51 | success: function (res) {
52 | if (res.statusCode != 200) {
53 | failc(new Error('上传错误:' + JSON.stringify(res)))
54 | return;
55 | }
56 | successc(aliyunServerURL+aliyunFileKey);
57 | },
58 | fail: function (err) {
59 | err.wxaddinfo = aliyunServerURL;
60 | failc(err);
61 | },
62 | })
63 | }
64 |
65 | const getPolicyBase64 = function () {
66 | let date = new Date();
67 | date.setHours(date.getHours() + env.timeout);
68 | let srcT = date.toISOString();
69 | const policyText = {
70 | "expiration": srcT, //设置该Policy的失效时间,超过这个失效时间之后,就没有办法通过这个policy上传文件了
71 | "conditions": [
72 | ["content-length-range", 0, 5 * 1024 * 1024] // 设置上传文件的大小限制,5mb
73 | ]
74 | };
75 |
76 | const policyBase64 = base64.encode(JSON.stringify(policyText));
77 | return policyBase64;
78 | }
79 |
80 | const getSignature = function (policyBase64) {
81 | const accesskey = env.AccessKeySecret;
82 |
83 | const bytes = Crypto.HMAC(Crypto.SHA1, policyBase64, accesskey, {
84 | asBytes: true
85 | });
86 | const signature = Crypto.util.bytesToBase64(bytes);
87 |
88 | return signature;
89 | }
90 |
91 | module.exports = uploadFile;
--------------------------------------------------------------------------------
/utils/util.js:
--------------------------------------------------------------------------------
1 | const formatTime = date => {
2 | const year = date.getFullYear()
3 | const month = date.getMonth() + 1
4 | const day = date.getDate()
5 | const hour = date.getHours()
6 | const minute = date.getMinutes()
7 | const second = date.getSeconds()
8 |
9 | return [year, month, day].map(formatNumber).join('-')
10 | // + ' ' + [hour, minute, second].map(formatNumber).join(':')
11 | }
12 |
13 | const formatNumber = n => {
14 | n = n.toString()
15 | return n[1] ? n : '0' + n
16 | }
17 |
18 | module.exports = {
19 | formatTime: formatTime
20 | }
21 |
--------------------------------------------------------------------------------