背景
最開始,后端同學(xué)許諾給前端返回一個鏈接,前端只用簡單的使用window.open打開即可,簡直不要太簡單。然而反轉(zhuǎn)開始了,一天后端同學(xué)反饋沒法提供給我鏈接(別問我為什么無法實現(xiàn),我要是知道我不就成全棧了嘛),只能先將一個html頁面 =>流 =>Base64編碼,前端拿著這個大字符串想辦法把頁面完整渲染出來。
分析
通過上面的背景,我們可以簡單的歸納為前端需要將Base64編碼展示成一個獨立頁面。首先我肯定第一時間跑到網(wǎng)上去看看有沒有作業(yè)可抄,結(jié)果當(dāng)然木有?;貋砘叵胍幌乱舱?,一般一個html格式文件給前端最簡單的方式就是給鏈接,誰會瞎折騰轉(zhuǎn)換來轉(zhuǎn)換去的。
分解步驟如下:
- 轉(zhuǎn)換Base64編碼為Blob二進制流
- 根據(jù)二進制流轉(zhuǎn)換成html實際內(nèi)容的字符串文本
- 新開頁面,在新頁面中寫入該html結(jié)構(gòu)的字符串
動手環(huán)節(jié)
轉(zhuǎn)換Base64編碼為Blob二進制流
一般來說,前端拿到Base64編碼的字符串沒法直接操作,需要先轉(zhuǎn)換成貼近實際文件的文件流Blob格式(如果不清楚Blob,可參考這里JS中的Blob對象)。其中需要注意關(guān)鍵Api是window.atob,瀏覽器原生方法,還有下面代碼的
{ type: fileType || 'pdf' }中的fileType是MIME類型。關(guān)鍵代碼如下:
// base64轉(zhuǎn)blob
function parseBase64ToBlob(dataUrl, fileType) {
const bstr = window.atob(dataUrl)
let n = bstr.length
const u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new Blob([u8arr], { type: fileType || 'pdf' })
}
let base64Str = "xxxxxx";//實際base64字符串
parseBase64ToBlob(base64Str,'text/plain');//text/plain原文格式
根據(jù)二進制流轉(zhuǎn)換成html實際內(nèi)容的字符串文本
現(xiàn)在拿到Blob對象了,該怎么轉(zhuǎn)換成明文(也就是開發(fā)人員能看懂的頁面結(jié)構(gòu)明文)呢?在得出結(jié)論前,我做了如下嘗試,通過URL.createObjectURL(myBlob)得到如下效果

好了,這就是我們開發(fā)人員能看懂的字符串了,接下來我就在想怎么提取出來。網(wǎng)上一搜,這篇帖子給了我實現(xiàn)方案js中Blob轉(zhuǎn)字符串,此步驟代碼如下:
var reader = new FileReader();
reader.onload = function(event){
var content = reader.result;//實際內(nèi)容就在這里
};
reader.readAsText(myBlob); //步驟一轉(zhuǎn)換后的blob
新開頁面,在新頁面中寫入該html結(jié)構(gòu)的字符串
直接參考js 打開空白頁,并在空白頁里展現(xiàn)內(nèi)容 代碼
var html="html代碼";
var open = window.open("about:blank", "_blank");
open.document.write(html);
完整代碼
好了,經(jīng)過上面三個步驟我們已經(jīng)可以實現(xiàn)想要的效果,下面就是把三個步驟的代碼合并一下,詳細(xì)代碼如下:
/**
*
* @param {*} base64Str 預(yù)覽html base64編碼的頁面
* @param {*} fileType 轉(zhuǎn)換的文件類型
*/
export function previewHtmlByBase64(base64Str, fileType) {
if (base64Str) {
const myBlob = parseBase64ToBlob(base64Str, fileType)
window.open(URL.createObjectURL(myBlob))
const reader = new FileReader()
reader.onload = function (event) {
const content = reader.result // 內(nèi)容就在這里
const open = window.open('about:blank', '_blank')
open.document.write(content)
}
reader.readAsText(myBlob)
}
}
function parseBase64ToBlob(dataUrl, fileType) {
const bstr = window.atob(dataUrl)
let n = bstr.length
const u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new Blob([u8arr], { type: fileType || 'pdf' })
}
let taxBase64 = "xxxxx";//替換成實際base64編碼字符串
previewHtmlByBase64(taxBase64, 'text/plain');