本文是团队技术分享大纲。实际分享结合代码演示,细节较多
Base64
目的:使用文本(ASCII)表示二进制。相当于64进制,使用64个可打印字符[A-Za-z+/]编码,当最后一块不够24bits时=用作填充
atob, btoa
可直接看polyfill来理解算法
developer.mozilla.org/zh-CN/docs/…
Unicode问题
developer.mozilla.org/zh-CN/docs/…javascripts_utf-16>_base64
应用
Data Urls
data:text/plain;base64,SGVsbG8sIFdvcmxkIQ
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAADAklEQVRYhe2WQWgUZxiGn/ffuFlrLkoIMbOsWQxWikcvPRVFqKaKyQhejKcipfRUPPQUiAcpHrx5kSL1IK0HXQ2SKqXUSo/VHkREZFNjM7OVZSkeQtls43wesqmandmMzUYP7Xub/3/ne56BYf6B/3qUtpi/lh+yhu1GtgtsyKAX1Le4a1VBDVTGdFNZ/RgcCMqrFhj6bihbn/9rLDI7jvFeWtnm5PtOOp3rfudCebjceG0B74o3Zhadxuh7LXAroSq54+FoeCGVwLZrA71zf/MVZiOrAreQdLVnHcceHqjUEgUGpwb7G/XGTbDtHYW/wD3I5rK7Zj6aedIiUJws9s0vzN9aO/gLie6u7g8eHXxUBXBLy41n81+3g0t6CkQpCFGzmxDbvshajIOlF86GY8Go4ZTZF/qVjcJtkXS3jeRd4baEfmWjU2afUOzbb2bD3hVvDMBN2IQjslOJvuJS4Ac3AMJDYWDGeGLXGA8PhQFA4Ac3TFxK6mL25YRNOHdu8uwewwaSi69eZtp8OVr2LLbW5Fv+3OTZPS6KOJJcA8Fhr+TtByhOFQsRnEzqRnCyOFUsAHglb7/gcLvZUaQj8kqbfzFjZ7ti02QO6Gn3VEvGwBxGz4ojxe0ug8KKcCDNwGYPSNc1KLjUg9ck6nHAzFvDQ+AkpTo21yJmzDikW29LQNJ1h3FeqP7m6SzkyH3jQj/8E7j45vlcnPanqw4gp/VfAE9WuKeDdNXW5zZ8Ds3DaNqfrnZJR9P/Ia4GDk7uk/JwufaPAMDvfuUHTJ+R7sj993DTsWA0KL209GrylzePGPrWsFxn2arj9Gk4Gp5f5tSafCm/N7Jn1zvIv71O2aOP/ccPlm+4uHbkonsdwYr7zunjbZvefT8ODtAVe1+k3fbSsSdUQfxq2A6MwbZM6SHYT85xeXbkj+8BAiqJ/VgBwz5sDnsKOtFf6D9zZ+edBYCtpa19ddV3mKxXpk1ERJJqjqhqmcxvswdnk2lxwnGLA6WBn2Xc25BlfPl//P/pdJ4DItcX43LWrMQAAAAASUVORK5CYII=
url-loader可以配置将小资源转化为base64编码直接嵌入代码,减少请求数
encodeURIComponent, decodeURIComponent, encodeURI, decodeURI
将url中的特殊字符进行16进制编码。% + 码点
ASCII
American Standard Code for Information Interchange,美国信息交换标准代码
Unicode
provide a unique code for every character, in every language, in every program, on every platform 为每个字符提供一个唯一的码点,不论什么语言,什么项目,什么平台
unicode规定了码点的对应关系,但如何存储不限制
实现方式:
UTF-32
固定长度32位,和Unicode一一对应
UTF-16
2-4位变长
UTF-8
1-4位变长
Unicode符号范围 | UTF-8编码方式
(十六进制) | (二进制)
----------------------+---------------------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
charCodeAt, codePointAt
charCodeAt: 返回 0 到 65535 之间的整数,表示给定索引处的 UTF-16 代码单元。如果index超出范围,返回 NaN。
codePointAt: 返回 一个 Unicode 编码点值的非负整数
问题:遍历字符串
let s = '𠮷a';
for (let ch of s) {
console.log(ch.codePointAt(0).toString(16));
}
// 20bb7
// 61
// 或Array.from
let arr = [...'𠮷a']; // arr.length === 2
arr.forEach(
ch => console.log(ch.codePointAt(0).toString(16))
);
// 20bb7
// 61
二进制
Number.property.toString(radix)
radix: 2-36, 大于10进制的会使用a-z表示大于9的数
ArrayBuffer,TypedArray, DataView
ArrayBuffer 表示通用的、固定长度的原始二进制数据缓冲区
Blob File
表示一个不可变、原始数据的类文件对象
API
Blob.stream()
Blob.text()
Blob.arrayBuffer()
Buffer
Uint8Array的子类
API
Buffer.from()
Buffer.concat()
URL.createObjectURL(object)
object: 用于创建 URL 的 File 对象、Blob 对象或者 MediaSource 对象。
应用
web中接收ArrayBuffer
const xhr = new XMLHttpRequest();
xhr.open("GET", "/foo.png", true);
xhr.responseType = "arraybuffer";
xhr.onload = function (e) {
const arrayBuffer = xhr.response;
// do something
};
xhr.send(null);
小程序中接收ArrayBuffer
wx.request({
url: 'www.foo.com',
responseType: 'arraybuffer',
});
小程序中上传ArrayBuffer
const fs = wx.getFileSystemManager();
fs.readFile({
filePath: 'foo.png',
success(data) {
wx.request({
url: 'www.foo.com',
data: data.slice(0, 1024 * 512),
});
},
});
实例
小程序大文件分段上传
/**
* Upload a part in a multipart upload transaction
* @param {String} name the object name
* @param {String} uploadId the upload id
* @param {Integer} partNo the part number
* @param {File} file upload File, whole File
* @param {Integer} start part start bytes e.g: 102400
* @param {Integer} end part end bytes e.g: 204800
* @param {Object} options
*/
export async function uploadPart(name, uploadId, partNo, file, start, end, options = {}) {
if (!is.arrayBuffer(file)) {
if (!options.mime) {
options.mime = mime.getType(path.extname(file));
}
file = await new Promise((resolve, rejcet) => {
fs.readFile({
filePath: file,
success: (res) => resolve(res.data),
fail: rejcet,
});
});
}
const data = file.slice(start, end);
return this._uploadPart(name, uploadId, partNo, data, options);
}
对唱歌词解密
const ENCRYPT_KEY = [63, 91, 97, 119, 94, 52, 39, 71, 86, 54, 49, 45, 02, 210, 110, 105];
export function decryptAndUnzip(xrc: ArrayBuffer): string {
// decrypt
const bytes = new Uint8Array(xrc);
const bytesLength = bytes.length;
const encryptKeyLength = ENCRYPT_KEY.length;
for (let i = 0; i < bytesLength; i += 1) {
// eslint-disable-next-line no-bitwise
bytes[i] ^= ENCRYPT_KEY[i % encryptKeyLength];
}
// unzip
return pako.inflate(bytes, { to: 'string' });
}
参考
en.wikipedia.org/wiki/Base64 developer.mozilla.org/zh-CN/docs/… es6.ruanyifeng.com/#docs/strin… www.ruanyifeng.com/blog/2007/1…