she says <h1> is large or she says <h1> is large 相信做过前端的小伙伴们都写过图片上传,最简单的方式是通过表单提交,一个<input type="file">加一个**<button type="submit">**,外面包一层form就搞定了。(button默认的type是submit,这里可以省略,之所以特别写出来,是因为以前碰到过form标签里面写了一个<button>标签,一点击就莫名奇妙地把表单提交了,希望大家引以为戒)
② 虽然知道了base64字符串所代表的二进制对象大小,但是要将文件上传,还是需要转化为真正的二进制Blob对象(另一种做法是直接提交base64字符串,后台对其进行转换,这么做的坏处是上传的数据量增大了 1/3)。Blob的构造函数可以接受一个类型数组,通过这个方式我们就可以将base64字符串还原为二进制对象,如果图方便,可以直接使用canvas的toBlob方法来直接生成Blob,不过ios似乎暂时并不支持原生的toBlob,这里可以使用MDN提供的基于toDataURL实现的polyfill:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
if (!HTMLCanvasElement.prototype.toBlob) { Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', { value: function (callback, type, quality) {
var binStr = atob( this.toDataURL(type, quality).split(',')[1] ), len = binStr.length, arr = newUint8Array(len); for (var i = 0; i < len; i++ ) { arr[i] = binStr.charCodeAt(i); } callback( newBlob( [arr], {type: type || 'image/png'} ) ); } }); }
③ 上面的polyfill用到了window.atob这个js原生方法,其作用是解码一个已经被base-64编码过的数据,相对应的还有一个window.btoa函数可以将ascii字符串或二进制数据转换成一个base64编码过的字符串,该方法不能直接作用于Unicode字符串(原因及解决办法见MDN的API文档),目前两个方法也都有兼容性问题,可以通过另一个polyfill来解决:
/** * Base64编/解码 * @type {{characters: string, encode: Base64.encode, decode: Base64.decode}} */ letBase64 = { characters: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=', /** * 对字符串编码 * @param {string} string * @returns {string} */ encode: function (string) { let characters = Base64.characters let result = ''
let i = 0 do { let a = string.charCodeAt(i++) let b = string.charCodeAt(i++) let c = string.charCodeAt(i++)
a = a || 0 b = b || 0 c = c || 0
let b1 = (a >> 2) & 0x3F let b2 = ((a & 0x3) << 4) | ((b >> 4) & 0xF) let b3 = ((b & 0xF) << 2) | ((c >> 6) & 0x3) let b4 = c & 0x3F
if (!b) { b3 = b4 = 64 } elseif (!c) { b4 = 64 }
result += characters.charAt(b1) + characters.charAt(b2) + characters.charAt(b3) + characters.charAt(b4)
} while (i < string.length)
return result },
/** * 对base64字符串解码 * @param {string} string * @returns {string} */ decode: function (string) { let characters = Base64.characters let result = ''
let i = 0 do { let b1 = characters.indexOf(string.charAt(i++)) let b2 = characters.indexOf(string.charAt(i++)) let b3 = characters.indexOf(string.charAt(i++)) let b4 = characters.indexOf(string.charAt(i++))
let a = ((b1 & 0x3F) << 2) | ((b2 >> 4) & 0x3) let b = ((b2 & 0xF) << 4) | ((b3 >> 2) & 0xF) let c = ((b3 & 0x3) << 6) | (b4 & 0x3F)