在此次的公衆號項目中,須要一個用戶的小程序二維碼,一開始想的是實時生成小程序二維碼,後臺問我行不行,隱約記得微信好像確實提供了這個功能,就答應下來了。一開始覺得只須要access_tojen我就能夠本身生成了,然而我好像忽略了跨域這件事。沒辦法,看來仍是得後臺中轉一下了。由於後臺暫時沒空,我就要了appid和secret先本身用node試試效果。javascript
getWXACodeUnlimit 文檔說的是:css
若是調用成功,會直接返回圖片二進制內容,若是請求失敗,會返回 JSON 格式的數據。html
二進制內容是什麼?ArrayBuffer仍是Blob?都試試吧。前端
隱約記得,XHR2能夠從服務器獲取其餘格式的數據了。java
值 | 數據類型 |
---|---|
'' | DOMString (這個是默認類型) |
arraybuffer | ArrayBuffer對象 |
blob | Blob對象 |
document | Document對象 |
json | JavaScript object, parsed from a JSON string returned by the server |
text | DOMString |
我一開始還覺得若是設置了responseType爲Blob的話,返回的是字符串。當時可真的是一頓操做猛如虎,一看結果250。 node
其實只要查看一下響應數據的constructor屬性就知道返回數據是什麼類型的了,回想起來真的是好尷尬,居然連這麼基礎的知識都忘了。ajax
廢話很少說,下面說個人解決方案吧。json
在這裏想出來3種辦法(_blob爲ajax請求獲得的Blob對象):小程序
var src = window.URL.createObjectURL(blob);
document.querySelector("#img").setAttribute("src", src)
// createObjectURL建立的數據不會自行釋放,因此無用的時候還得調用以下方法進行手動釋放
window.URL.revokeObjectURL(src)
複製代碼
var reader = new FileReader();
reader.onload = (e) => {
document.querySelector("#img").setAttribute("src", reader.result)
}
reader.readAsDataURL(_blob);
複製代碼
// 假設接口的地址是 http://test.com/index/getWxImg
// html
<img src="http://test.com/index/getWxImg" alt="微信小程序二維碼" />
複製代碼
這就至關於在瀏覽器地址欄直接經過url訪問該圖片了,他會自動根據響應頭的 Content-Type 和 響應數據進行展現。固然了,這種方式只限於 get 請求,若是接口的請求方式只能是 post, 就只能用前兩種方式了。微信小程序
此次可真是鬧了一個大烏龍,痛定思痛,我決定對 ArrayBuffer 和 Blob 進行一個較爲深刻的理解。
二進制數組(ArrayBuffer對象、TypedArray視圖和DataView視圖)是JavaScript操做二進制數據的一個接口。 這個接口的原始設計目的,與WebGL項目有關。所謂WebGL,就是指瀏覽器與顯卡之間的通訊接口,爲了知足JavaScript與顯卡之間大量的、實時的數據交換,它們之間的數據通訊必須是二進制的,而不能是傳統的文本格式。文本格式傳遞一個32位整數,兩端的JavaScript腳本與顯卡都要進行格式轉化,將很是耗時。這時要是存在一種機制,能夠像C語言那樣,直接操做字節,將4個字節的32位整數,以二進制形式原封不動地送入顯卡,腳本的性能就會大幅提高。
Blob 對象表示一個不可變、原始數據的類文件對象。Blob 表示的不必定是JavaScript原生格式的數據。File 接口基於Blob,繼承了 blob 的功能並將其擴展使其支持用戶系統上的文件。
Blob的構造函數爲 Blob(blobParts[, options])。第一個參數必須爲數組,能夠是字符串數組,能夠是二進制數組。options是一個對象,主要經過設置 type 值來指定文件的 content-type。
簡單來講,能夠直接把ArrayBuffer當成二進制數組,而把Blob當成是二進制數據。(這麼說沒錯吧?若是理解的不對,歡迎指正。)
function dataURL2Blob(dataurl) {
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime });
}
複製代碼
function plain2Blob(text, type) {
return new Blob([text], { type: 'text/plain' });
}
複製代碼
function buffer2Blob(_buffer, type) {
return new Blob([_buffer], { type: 'application/octet-stream' });
}
複製代碼
從Blob中讀取內容的惟一方法是使用 FileReader。
var _blob = new Blob([]); //假設它是一個有效的Blob對象
var reader = new FileReader();
reader.onload = (e) => {
console.log(reader.result)
}
複製代碼
reader.readAsDataURL(_blob);
reader.readAsText(_blob);
reader.readAsArrayBuffer(_blob);
// @params content: String
// @params type: String
// @params filename: String
function downloadFile(content, type = 'text', filename) {
var textBlob;
if (type === 'img') {
textBlob = dataURL2Blob(content);
if (!filename) {
throw new Error('type爲img時, filename 文件名參數必傳');
}
} else {
textBlob = plain2Blob(content, type);
filename = filename || generateFilename(type);
}
var a = document.createElement("a"),
href = URL.createObjectURL(textBlob);
a.href = href;
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(href);
}
function dataURL2Blob(dataurl) {
var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime });
}
function plain2Blob(text, type) {
var fileTypes = {
text: 'text/plain',
svg: 'image/svg+xml',
}
return new Blob([text], { type: fileTypes[type] || 'application/octet-stream' })
}
function generateFilename(type) {
var prefixs = {
text: 'txt',
svg: 'svg',
}
return '1.' + (prefixs[type] || '.txt')
}
複製代碼
// 下載txt文件
downloadFile(`測試\r\n第二行`, 'text',)
// 下載svg
downloadFile(`<svg version="1.1" id="tuceng_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="80px" height="36px" viewBox="0 0 80 36" enable-background="new 0 0 80 36" xml:space="preserve"> <rect y="34.129" fill="#009944" width="36" height="2"/> </svg>`, 'svg', '1.svg')
// 下載圖片
var data = 'data:image/png;base64,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';
downloadFile(data, 'img', '1.png')
複製代碼
目前只支持文本文件,svg,圖片三種格式。
Blob的做用仍是蠻大的,在必定程度上能夠在前端直接生成文件從而進行上傳或者下載。
File 也是 繼承自 Blob, 因此生成的 圖片Blob 也是能夠直接經過 ajax 上傳 OSS 之類的進行存儲。以前有一個項目其中一部分是 在線PPT,我就是用 Blob 上傳 PPT的首圖 到 OSS 的。