編碼 data text html c,誰說前端不需要懂二進制

作者:全棧成長之路?公號 / 山月行

作為一名前端,在工作中也會遇到很多有關二進制處理的需求,如 EXCEL 表格的導出,PDF 的生成,多個文件的打包,音頻的處理。

從前后端整體上來說前端代表 UI 層,它的外在表現是?human readable?的,而服務端代表數據層,所表現出來的是?machine readable。如果 EXCEL 以及 PDF 的處理交由服務端處理,服務端免不了要做一層格式化的邏輯處理,以便與前端保持一致。一來增加了復雜度,二來容易造成前端與服務器端的數據不一致。此時為了減少復雜度,工作量有可能都盡可能在瀏覽器端完成。

本篇文章總結了瀏覽器端的二進制以及有關數據之間的轉化,如?ArrayBuffer,TypedArray,Blob,DataURL,ObjectURL,Text?之間的互相轉換。為了更好的理解與方便以后的查詢,特意做了一張圖做總結。

1593182845-4161-aVicAicMn9vacsn3MJXHzzcfB1MA.jpg二進制相互轉換圖

二進制相關數據類型

在介紹常見的二進制數據處理之前,先簡單介紹下幾種二進制相關的數據類型

ArrayBuffer && TypedArray

TypedArray?是 ES6+ 新增的描述二進制數據的類數組數據結構。但它本身不可以被實例化,甚至無法訪問,你可以把它理解為?Abstract Class?或者?Interface。而基于?TypedArray,有如下數據類型:

Uint8ArrayUint?及?Unsigned Int?代表數組的每一項是無符號整型8?代表數據的每一項占 8 個比特位,即一個字節

Int8Array

Uint16Array

Int16Array

...

通過?Uint8Array,即可知道?Uint16Array,Int8Array?所代表的意義。

const?array?=?new?Int32Array([1,?2,?3])

//?.length?代表數組的大小

//?3

array.length

//?.btyeLength?代表數據所占字節大小

//?12

array.byteLength

ArrayBuffer?代表二進制數據結構,「并且只讀」,需要轉化為?TypedArray?進行寫操作。

const?array?=?new?Int16Array([1,?2,?3])

//?TypedArray?->?ArrayBuffer

array.buffer

//?ArrayBuffer?->?TypedArray

new?Int16Array(array.buffer)

//?buffer.length?代表數據所占用字節大小

array.buffer.length?===?array.byteLength

連接多個 TypedArray

TypedArray?沒有像數組那樣的?Array.prototype.concat?方法用來連接多個?TypedArray。不過它提供了?TypedArray.prototype.set?可以用來間接連接字符串

?可以參考 MDN 文檔:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set

?

//?在位移?offset?位置放置?typedarray

typedarray.set(typedarray,?offset)

原理就是先分配一塊空間足以容納需要連接的?TypedArray,然后逐一在對應位置疊加

function?concatenate(constructor,?...arrays)?{

let?length?=?0;

for?(let?arr?of?arrays)?{

length?+=?arr.length;

}

let?result?=?new?constructor(length);

let?offset?=?0;

for?(let?arr?of?arrays)?{

result.set(arr,?offset);

offset?+=?arr.length;

}

return?result;

}

concatenate(Uint8Array,?new?Uint8Array([1,?2,?3]),?new?Uint8Array([4,?5,?6]))

同時您還需要對資源的獲取有大致的了解,如 XHR,fetch,通過文件上傳。

Blob

Blob?是瀏覽器端的類文件對象。操作?Blob?需要使用數據類型?FileReader。

FileReader?有以下方法,可以把?Blob?轉化為其它數據

FileReader.prototype.readAsArrayBuffer

FileReader.prototype.readAsText

FileReader.prototype.readAsDataURL

FileReader.prototype.readAsBinaryString

const?blob?=?new?Blob('hello'.split(''))

//?表示文件的大小

blob.size

const?array?=?new?Uint8Array([128,?128,?128])

const?blob2?=?new?Blob([array])

function?readBlob?(blob,?type)?{

return?new?Promise(resolve?=>?{

const?reader?=?new?FileReader()

reader.onload?=?function?(e)?{

resolve(e.target.result)

}

reader.readAsArrayBuffer(blob)

})

}

readBlob(blob,?'DataURL').then(url?=>?console.log(url))

數據輸入

數據輸入或者叫資源的請求可以分為以下兩種途徑

通過 url 地址請求網絡資源

通過文件上傳請求本地資源

fetch

fetch?應該是大家比較熟悉的,但大多使用環境比較單一,一般用來請求 json 數據。其實,?「它也可以設置返回數據格式為?Blob?或者?ArrayBuffer。」

fetch?返回一個包含?Response?對象的 Promise,Response?有以下方法

Response.prototype.arrayBuffer

Response.prototype.blob

Response.prototype.text

Response.prototype.json

?詳情可以查看 MDN 文檔 https://developer.mozilla.org/en-US/docs/Web/API/Response

?

fetch('/api/ping').then(res?=>?{

//?true

console.log(res?instanceof?Response)

//?最常見的使用

return?res.json()

//?返回?Blob

//?return?res.blob()

//?返回?ArrayBuffer

//?return?res.arrayBuffer()

})

另外,萬能的?Response API?既可以可以使用?TypedArray,Blob,Text?作為輸入,又可以使用它們作為輸出。

「這意味著關于這三種數據類型的轉換完全可以通過 Response」

xhr

「xhr 可以設置 responseType 接收合適的數據類型」

const?request?=?new?XMLHttpRequest()

request.responseType?=?'arraybuffer'

request.responseType?=?'blob'

File

本地文件可以通過?input[type=file]?來上傳文件。

當上傳成功后,可以通過?document.getElementById('input').files[0]?獲取到上傳的文件,即一個 File 對象,它是 Blob 的子類,可以通過?FileReader?或者?Response?獲取文件內容。

數據輸出

或者叫數據展示或者下載,數據經二進制處理后可以由 url 表示,然后通過 image, video 等元素引用或者直接下載。

Data URL

Data URL 即 Data As URL。所以,?「如果資源過大,地址便會很長。」?使用以下形式表示。

data:[][;base64],

先來一個 hello, world。把以下地址粘入地址欄,會訪問到 hello, world

data:text/html,

Hello%2C%20World!

Base64 編碼與解碼

Base64 使用大小寫字母,數字,+ 和 / 64 個字符來編碼數據,所以稱為 Base64。經編碼后,文本體積會變大 1/3

在瀏覽器中,可以使用?atob?和?btoa?編碼解碼數據。

//?aGVsbG8=

btoa('hello')

Object URL

可以使用瀏覽器新的 API?URL?對象生成一個地址來表示?Blob?數據。

//?粘貼生成的地址,可以訪問到?hello,?world

//?blob:http://host/27254c37-db7a-4f2f-8861-0cf9aec89a64

URL.createObjectURL(new?Blob('hello,?world'.split('')))

下載

data:application/octet-stream;base64,5bGx5pyI

資源的下載可以利用 FileSaver[1]?。

這里也簡單寫一個函數,用來下載一個鏈接

function?download?(url,?name)?{

const?a?=?document.createElement('a')

a.download?=?name

a.rel?=?'noopener'

a.href?=?url

//?觸發模擬點擊

a.dispatchEvent(new?MouseEvent('click'))

//?或者?a.click(

}

二進制數據轉換

1593182845-1658-aVicAicMn9vacsn3MJXHzzcfB1MA.jpg二進制數據轉換

以上是二進制數據間的轉換圖,有一些轉換可以直接通過 API,有些則需要代碼,以下貼幾種常見轉換的代碼

String to TypedArray

根據上圖,由字符串到 TypedArray 的轉換,可以通過?「String -> Blob -> ArrayBuffer -> TypedArray」?的途徑。

關于代碼中的函數?readBlob?可以回翻環節 數據類型 - Blob[2]

const?name?=?'山月'

const?blob?=?new?Blob(name.split(''))

readBlob(blob,?'ArrayBuffer').then(buffer?=>?new?Uint8Array(buffer))

也可以通過 Response API 直接轉換?「String -> ArrayBuffer -> TypedArray」

const?name?=?'山月'

new?Response(name).arrayBuffer(buffer?=>?new?Uint8Array(buffer))

這上邊兩種方法都是直接通過 API 來轉化,如果你更像了解如何手動轉換一個字符串和二進制的 TypedArray

String to TypedArray 2

使用 enodeURIComponent 把字符串轉化為 utf8,再進行構造 TypedArray。

function?stringToTypedArray(s)?{

const?str?=?encodeURIComponent(s)

const?binstr?=?str.replace(/%([0-9A-F]{2})/g,?(_,?p1)?=>?{

return?String.fromCharCode('0x'?+?p1)

})

return?new?Uint8Array(binstr.split('').map(x?=>?x.charCodeAt(0)))

}

實踐

1. 如何上傳本地圖片并在網頁上展示

由以上整理的轉換圖得出途徑

本地上傳圖片 -> Blob -> Object URL

2. 如何拼接兩個音頻文件

由以上整理的轉換圖得出途徑

fetch請求音頻資源 -> ArrayBuffer -> TypedArray -> 拼接成一個 TypedArray -> ArrayBuffer -> Blob -> Object URL

3. 如何把 json 數據轉化為 demo.json 并下載文件

json 視為字符串,由以上整理的轉換圖得出途徑

Text -> DataURL

除了使用 DataURL,還可以轉化為 Object URL 進行下載。關于下載的函數?download,可以參考以上環節 數據輸出-下載[3]

Text -> Blob -> Object URL

可以把以下代碼直接粘貼到控制臺下載文件

const?json?=?{

a:?3,

b:?4,

c:?5

}

const?str?=?JSON.stringify(json,?null,?2)

//?方案一:Text -> DataURL

const?dataUrl?=?`data:,${str}`

download(dataUrl,?'demo.json')

//?方案二:Text -> Blob -> ObjectURL

const?url?=?URL.createObjectURL(new?Blob(str.split('')))

download(url,?'demo1.json')

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/530810.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/530810.shtml
英文地址,請注明出處:http://en.pswp.cn/news/530810.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

計算機動漫與游戲制作專業大學有哪些,西安鐵道職業學校計算機動漫與游戲制作專業從事什么工作?...

西安鐵道職業學校坐落于陜西省西安市灞橋區朝陽工業園,占地400余畝,總建筑面積30余萬平方米,學校緊鄰火箭軍工程大學(二炮學院)。學校建有多功能軌道教學大樓、電子閱覽室、軌道綜合實訓樓、室外軌道實訓基地、乘務形體訓練中心等先進教學設施…

小學四年級計算機制作月歷教案,四年級上冊信息技術教案-1制作月歷|冀教版(5頁)-原創力文檔...

制作月歷教學目標:1、認識Word,學會美化月歷。2、鍛煉學生協同合作解決問題的能力。3、培養學生探究問題的能力,在制作月歷的過程中體驗學習的樂趣。學情分析:本課主要任務是安排學生利用word文檔制作一張月歷,在此之前&#xff0…

計算機聯用測定無機鹽溶解熱測試題,計算機聯用測定無機鹽溶解熱

計算機聯用測定無機鹽溶解熱計算機聯用測定無機鹽溶解熱一 實驗目的1. 用量熱計測定KCl的積分溶解熱。2. 掌握量熱實驗中溫差校正方法以及與計算機聯用測量溶解過程動態曲線的方法。二 實驗原理鹽類的溶解過程通常包含著兩個同時進行的過程:晶格的破壞和離子的溶劑化…

通過微型計算機的電流,單板微型計算機控制的電流型變頻調速系統

單板微型計算機控制的電流型變頻調速系統介紹用8位單板微型計算機控制的電流型變頻調速系統。系統利用軟件實(本文共4頁)閱讀全文>>空間矢量脈寬調制(SVPWM)技術運用于變頻調速系統具有直流電壓利用率高,功率器件的開關損耗小,電流諧波抑制效果好等明顯優勢。本文給出了一…

初中計算機考試用什么軟件,初中信息技術《PowerPoint軟件》考過啥

教師資格考試的試題中,不會缺少辦公軟件的身影,而辦公軟件作為最重要的文字處理工具,都考過哪些題目呢?該如何學習呢?中公教師給您指引方向。一、考題集錦1.PowerPoint中,為了讓海龜按圖1所示路線運動,應采用的方法是…

達內計算機畢業好找工作嗎,大學生學什么好找工作 轉行IT行業需要多久

6月畢業季,工作好找嗎?9月招聘季,求職順利嗎?一直以來工作難找、人難招究竟難在哪?而另一邊,企業求賢若渴,主動搶奪優秀人才!卻有很多畢業生抱怨求職難,找不到理想的工作…

華為trt一al00計算機在哪,華為trt一al00a屬于什么系列

大家好,我是智能客服時間君,上述問題將由我為大家進行解答。華為trt一al00a是華為暢享7 Plus全網通標配3GB32GB版,屬于華為暢享系列。華為暢享7 Plus是華為暢享系列首款5.5英寸大屏手機,Slogan是“玩到爽快到爽”,主打…

ajax數據交互代碼,Django中使用jquery的ajax進行數據交互的實例代碼

jquery框架中提供了$.ajax、$.get、$.post方法,用于進行異步交互,由于Django中默認使用CSRF約束,推薦使用$.get示例:實現省市區的選擇最終實現效果如圖:將jquery文件拷貝到static/js/目錄下打開booktest/views.py文件&…

MySQL 入門教程:全網最全,MySQL 增刪改查高級命令硬核總結

文章目錄前言一、連接到 MySQL 數據庫1.1、連接到本機上的 MySQL1.2、連接到遠程主機上的 MySQL二、退出 MySQL 命令三、修改 MySQL 密碼3.1、先給 root 用戶加個密碼 ab123.2、再將 root 用戶的密碼改為 djg345四、增加新用戶4.1、增加一個可以在任何主機上登錄用戶 test1&…

網站設計好怎么上傳到服務器的,虛擬主機上傳到網站的幾個步驟

虛擬主機怎么上傳到網站?站長們可以利用專業的軟件協助自己上傳,比如專業的ftp軟件,具備支持續點相傳,上傳,以及下載目錄等等,不會將限制過長的網站剔除,還可以下載列隊,可以長傳到本地&#x…

數據庫管理工具:全網最全,MySQL 數據庫圖形化管理界面應用 Navicat Premium 使用教程

文章目錄前言一、Navicat 下載和安裝1.1、Navicat 下載1.2、Navicat 安裝和啟動二、創建數據庫連接2.1、連接本地數據庫2.2、連接遠程數據庫三、對數據庫的“增刪改查”功能操作3.1、對數據庫的基本操作3.1.1、新建數據庫3.1.2、刪除數據庫3.1.3、修改數據庫3.1.4、查詢數據庫3…

電腦無線網絡與服務器共享,圖文詳解win7筆記本如何實現內置無線局域網卡共享...

圖文詳解win7筆記本如何實現內置無線局域網卡共享:windows7集合了眾多優點于一身,帶來了空前的操作體驗,同時還吸取了蘋果Mac OS X系統的特色,因此很多用戶在新購置筆記本電腦的時候都預裝了win7系統,而且現在市面上出…

數據庫深度剖析:Oracle、Microsoft SQL Server、MySQL 三者有何區別?

文章目錄前言一、Oracle 數據庫1.1、支撐平臺范圍廣1.2、Oracle 在兼容性、可移植性、可聯結性、高生產率上、開放性也存在優點1.3、Oracle 價格是比較昂貴的二、Microsoft SQL Server 數據庫2.1、可伸縮性好、與相關軟件集成程度高2.2、擁有良好的 ODBC 接口2.3、基于微軟&…

MySQL 完全卸載:教你如何完全卸載掉本地令人頭大的 MySQL 數據庫

文章目錄前言一、控制面板卸載 MySQL二、刪除 MySQL 數據庫安裝文件夾三、打開注冊表編輯器四、刪除殘留注冊表文件五、刪除系統盤殘留數據文件總結前言 如果我們 MySQL 數據庫密碼遺忘需要重新安裝 MySQL 數據庫時,就需要先卸載掉本地的文件。而 MySQL 并不是像其他…

MySQL 外碼約束原理:如何解決數據庫添加數據時產生的外碼(外鍵)約束?

文章目錄前言一、插入新數據時報錯外鍵約束?二、對于出錯 SQL 語句的分析三、對于外碼約束的分析四、如何處理外鍵約束?總結前言 我們在使用 MySQL 數據庫時,添加數據如果設計不合理很容易出現外碼約束的情況,為什么會產生這樣的問…

MySQL 案例練習:用一條 SQL 語句查詢出每門課都大于 80 分的學生姓名

用一條sql語句查詢出每門課都大于80分的學生姓名 首先需要進行分析: 要查詢出每門課程都大于80分的學生姓名,因為一個學生有多門課程,所以會出現下面三種情況。 第一可能所有課程都大于80分。第二可能有些課程大于80分,另外一些…

如何刪除 eclipse 中多余的 Tomcat server?為什么產生這種 bug?

文章目錄前言一、錯誤原因分析二、解決方式總結前言 可能有些同學在使用 Eclipse 進行項目開發的時候,存在對于 Tomcat 的錯誤操作,會發現在下面的工具欄里 Server 的選項里面有好多 Server,按理說我們有一個可以使用就行了。那我們該如何刪除…

HTTP 和 HTTPS 兩種傳輸協議各自含義是什么?二者使用有什么區別?

文章目錄前言一、什么是 HTTP 傳輸協議?二、什么是 HTTPS 傳輸協議?三、HTTP 和 HTTPS 有何區別?總結前言 HTTP 屬于超文本傳輸協議,用來在 Internet 上傳送超文本,而 HTTPS 為安全超文本傳輸協議,在 HTTP基…

在前端網頁設計中 align 和 valign 兩種對齊方式的不同取值區分(持續補充)

文章目錄前言一、align 與 valign 的對齊方式與取值二、常見應用區分整理2.1、H5 頁面設計的取值2.2、表格標題的取值2.3、表格屬性的取值總結前言 不知道大家在學習 H5 的時候,有沒有疑惑過,對于 align 和 valign 兩種對齊方式在不同的情境下往往會有不…

H5 中 bordercolorlight 屬性的用法及作用

一、問題場景 今天在復習 H5 頁面設計表格&#xff0c;發現<table>標簽中添加了新的屬性&#xff1a;bordercolorlight。我們來看看有什么作用。 示例如下&#xff1a; table bordercolorlight"顏色值"&#xff08;黃色部分&#xff09;效果如下圖所示&…