I. Base64
1. Intro.
可用文字形式传输或储存二进位资料(binary data),也包括MIME及XML每6个位元(bit)为一组Base64 unit,每个unit可对应 2^6=64 个可列印字元:A-Z, a-z, 0-9 & 2个视情况而定的符号一个binary data中,1字元 = 1位元组 (1byte) = 8bit
,所以3字元 = 3byte = 24bit = 4个Base64 unit
。因此编码后字串长度会变成原本的 3/4 倍 (约略)若不是3的倍数则补 =
:余1补 ==
、余2补 =
将3个二进位byte转为4个Base64 units (from wiki)
2. In JavaScript
String encoded to base64 string: btoa() let binaryString1 = "Hello JS world!" // length = 15 // btoa() 编码为Base64 btoa(binaryString1) // 输出: "SGVsbG8gSlMgd29ybGQh", length = 20 let binaryString2 = "Hello JS world" // length = 14 ... 余2 btoa(binaryString2) // 输出: "SGVsbG8gSlMgd29ybGQ=", length = 20, 末端补 "="
Base64 decoded to string: atob() let base64String = "WW91IGNhdGNoZWQgbWUh" // atob() 解码 atob(base64String) // 输出: "You catched me!"
II. Web API
1. FileReader物件
非同步读取client side档案内容读取结果会在FileReader.result物件中,形式则是看用哪个method读取。例如:用readAsDataURL()则回传Base64编码字串;用readAsArrayBuffer()则回传ArrayBuffer物件档案来源: File object<input type="file">
中取得的Filedrag/drop事件中的 event.originalEvent.dataTransfer.files
2. HTML部分:随意建立一下
<style> // 给拖曳区画个框线 #dragArea { width:200px; border-style:dashed; border-width:0.2em; height:200px; } h4 { margin:20px auto 10px; }</style>// input浏览档案<h4>Upload image:</h4><form enctype="multipart/form-data"> <input id="uploadImage" type="file" accept="image/*"></form>// 拖曳放置档案<h4>Or drop image here:</h4><div id="dragArea"></div>// 预览档案<h4>Preview:</h4><div id="previewDiv"></div>
3. JavaScript部分:
// 预览图片,将取得的files一个个取出丢到convertFile()function previewFiles(files) { if (files && files.length >= 1) { $.map(files, file => { convertFile(file) .then(data => { console.log(data) // 把编码后的字串输出到console showPreviewImage(data, file.name) }) .catch(err => console.log(err)) }) }}// 使用FileReader读取档案,并且回传Base64编码后的sourcefunction convertFile(file) { return new Promise((resolve,reject)=>{ // 建立FileReader物件 let reader = new FileReader() // 注册onload事件,取得result则resolve (会是一个Base64字串) reader.onload = () => { resolve(reader.result) } // 注册onerror事件,若发生error则reject reader.onerror = () => { reject(reader.error) } // 读取档案 reader.readAsDataURL(file) })}// 在页面上新增<img>function showPreviewImage(src, fileName) { let image = new Image(250) // 设定宽250px image.name = fileName image.src = src // <img>中src属性除了接url外也可以直接接Base64字串 $("#previewDiv").append(image).append(`<p>File: ${image.name}`)}// 当上传档案改变时清除目前预览图,并且呼叫previewFiles()$("#upimg").change(function(){ $("#previewDiv").empty() // 清空当下预览 previewFiles(this.files) // this即为<input>元素})// dragover事件:拖曳(滑鼠还没鬆开)至放置区时,就要先防止浏览器进行开图$("#dragArea").on("dragover", function(e) { e.preventDefault()})// 当拖曳区发生drop事件时,接受格式为image的资料$("#dragArea").on("drop", function(e){ // 防止事件传递及预设事件发生 e.stopPropagation() e.preventDefault() // 取得data type为image/*的资料 e.originalEvent.dataTransfer.getData("image/*") let files = e.originalEvent.dataTransfer.files console.dir(files) // 看看File长什么样子 $("#previewDiv").empty() // 清空当下预览 previewFiles(files)})
4. 结果 & 备注
尝试浏览图片或是拖曳图片后,可以在chrome console上看到FileReader读出的Base64字串

III. 参考
Base64: https://zh.wikipedia.org/wiki/Base64
Web API/FileReader: https://developer.mozilla.org/zh-TW/docs/Web/API/FileReader
Web API/Image: https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/Image
Event/drop: https://developer.mozilla.org/en-US/docs/Web/Events/drop