狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發文檔 其他文檔  
 
網站管理員

http-為什么文件上傳要轉成Base64編碼而不是采用二進制流

admin
2023年7月13日 10:24 本文熱度 1348

1 前言

最近在開發中遇到文件上傳采用Base64的方式上傳,記得以前剛開始學http上傳文件的時候,都是通過content-type為multipart/form-data方式直接上傳二進制文件,我們知道都通過網絡傳輸最終只能傳輸二進制流,所以毫無疑問他們本質上都是一樣的,那么為什么還要先轉成Base64呢?這兩種方式有什么區別?帶著這樣的疑問我們一起來分析下。

2 multipart/form-data上傳

先來看看multipart/form-data的方式,我在本地通過一個簡單的例子來查看http multipart/form-data方式的文件上傳,html代碼如下

html復制代碼<!DOCTYPE html>
<html>
<head>
   <title>上傳文件示例</title>
   <meta charset="UTF-8">
<body>
<h1>上傳文件示例</h1>
<form action="/upload" method="POST" enctype="multipart/form-data">
   <label for="file">選擇文件:</label>
   <input type="file" id="file" name="file"><br>
   <label for="tx">說明:</label>
   <input type="text" id="tx" name="remark"><br><br>
   <input type="submit" value="上傳">
</form>
</body>
</html>

頁面展示也比較簡單


選擇文件點擊上傳后,通過edge瀏覽器f12進入調試模式查看到的請求信息。
請求頭如下


在請求頭里Content-Type 為 multipart/form-data; boundary=
----WebKitFormBoundary4TaNXEII3UbH8VKo,剛開始看肯定有點懵,不過其實也不復雜,可以簡單理解為在請求體里要傳遞的參數被分為多部份,每一部分通過分解符boundary分割,就比如在這個例子,表單里有file和remark兩個字段,則在請求體里就被分為兩部分,每一部分通過boundary=----WebKitFormBoundary4TaNXEII3UbH8VKo來分隔(實際上還要加上CRLF回車換行符,回車表示將光標移動到當前行的開頭,換行表示一行文本的結束,也就是新文本行的開始)。需要注意下當最后一部分結尾時需要加多兩個"-"結尾。

我們繼續來看請求體


第一部分是file字段部分,它的Content-Type為image/png,第二部分為remark字段部分,它沒有聲明Content-Type,則默認為text/plain純文本類型,也就是在例子中輸入的“測試”,到這里大家肯定會有個疑問,上傳的圖片是放在哪里的,這里怎么沒看到呢?別急,我猜測是瀏覽器做了特殊處理,請求體里不顯示二進制流,我們通過Filder抓包工具來驗證下。


可以看到在第一部分有一串亂碼顯示,這是因為圖片是二進制文件,顯示成文本格式自然就亂碼了,這也證實了二進制文件也是放在請求體里。后端使用框架springboot通過MultipartFile接受文件也是解析請求體的每一部分最終拿到二進制流。

java復制代碼@RestController
public class FileController {
   // @RequestParam可接收Content-Type 類型為:multipart/form-data
   // 或 application/x-www-form-urlencoded 請求體的內容
   @PostMapping("/upload")
   public String upload(@RequestParam("file") MultipartFile file) {
       return "test";
   }
}

到此multipart/form-data方式上傳文件就分析完了,關于multipart/form-data官方說明可參考 RFC 7578 - Returning Values from Forms: multipart/form-data (ietf.org)

3 Base64上傳

在http的請求方式中,文件上傳只能通過multipart/form-data的方式上傳,這樣一來就會有比較大的限制,那有沒其他方式可以突破這一限制,也就是說我可以通過其他的請求方式上傳,比如application/json?當然有,把文件當成一個字符串,和其他普通參數沒什么兩樣,我們可以通過其他任意請求方式上傳。如果轉成了字符串,那上傳文件就比較簡單了,但問題是我們怎么把二進制流轉成字符串,因為這里面可能會有很多“坑”,業界一般的做法是通過Base64編碼把二進制流轉成字符串,那為什么不直接轉成字符串而要先通過Base64來轉呢?我們下面來分析下。

3.1 Base64編碼原理

在分析原理之前,我們先來回答什么是Base64編碼?首先我們要知道Base64只是一種編碼方式,并不是加解密算法,因此Base64可以編碼,那也可以解碼,它只是按照某種編碼規則把一些不可顯示字符轉成可顯示字符。這種規則的原理是把要編碼字符的二進制數每6位分為一組,每一組二進制數可對應Base64編碼的可打印字符,因為一個字符要用一個字節顯示,那么每一組6位Base64編碼都要在前面補充兩個0,因此總長度比編碼前多了(2/6) = 1/3,因為6和8最小公倍數是24,所以要編碼成Base64對字節數的要求是3的倍數(24/8=3字節),對于不足字節的需要在后面補充字節數,補充多少個字節就用多少個"="表示(一個或兩個),這么說有點抽象,我們通過下面的例子來說明。


我們對ASCII碼字符串"AB\nC"(\n和LF都代表換行)進行Base64編碼,因為一共4字節,為了滿足是3的倍數需要擴展到6個字節,后面補充了2個字節。


表3.1

轉成二級制后每6位一組對應不同顏色,每6位前面補充兩個0組成一個字節,最終Base64編碼字符是QUIKQw==,Base64編碼表大家可以自行網上搜索查看。


我們通過運行程序來驗證下


最終得出的結果與我們上面推理的一樣。

3.2 Base64編碼的作用

在聊完原理之后,我們繼續來探討文件上傳為什么要先通過Base64編碼轉成字符串而不直接轉成字符串?一些系統對特殊的字符可能存在限制或者說會被當做特殊含義來處理,直接轉成普通字符串可能會失真,因此上傳文件要先轉成Base64編碼字符,不能把二進制流直接字符串。

另外,相比較multipart/form-data Base64編碼文件上傳比較靈活,它不受請求類型的限制,可以是任何請求類型,因為最終就是一串字符串,相當于請求的一個參數字段,它不像二進制流只能限定multipart/form-data的請求方式,日常開發中,我們用的比較多的是通過apllication/json的格式把文件字段放到請求體,這種方式提供了比較便利的可操作性。

4 總結

本文最后再來總結對比下這兩種文件上傳的方式優缺點。
(1)multipart/form-data可以傳輸二進制流,效率較高,Base64需要編碼解碼,會耗費一定的性能,效率較低。
(2)Base64不受請求方式的限制,靈活度高,http文件二進制流方式傳輸只能通過multipart/form-data的方式,靈活度低。
因為隨著機器性能的提升,小文件通過二進制流傳輸和字符串傳輸,我們對這兩種方式時間延遲的感知差異并不那么明顯,因此大部分情況下我們更多考慮的是靈活性,所以采用Base64編碼的情況也就比較多。


該文章在 2023/7/13 10:24:07 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業的專業生產管理軟件系統,系統成熟度和易用性得到了國內大量中小企業的青睞。
點晴PMS碼頭管理系統主要針對港口碼頭集裝箱與散貨日常運作、調度、堆場、車隊、財務費用、相關報表等業務管理,結合碼頭的業務特點,圍繞調度、堆場作業而開發的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業的高效ERP管理信息系統。
點晴WMS倉儲管理系統提供了貨物產品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質期管理,貨位管理,庫位管理,生產管理,WMS管理系統,標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協同辦公管理系統。
Copyright 2010-2025 ClickSun All Rights Reserved