日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

http上传文件原理

發布時間:2023/12/31 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 http上传文件原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文件上傳下載,說來悲劇。
以前都是用的ADF\OAF\JALOR等框架開發,SE搭好工程,只負責業務邏輯開發,基本沒怎么想過為什么。
直到一天,為了防止系統入侵,做文件上傳現在過濾攔截,才想到一個問題。我們上傳下載的原理到底是什么?一直再copy代碼,為什么要這么做哪?

我們用一個servlet去處理一個上傳文件,看下代碼很簡單,基本是從request讀取流,然后通過IO寫入到指定目錄,或者通過一些中間件寫入一些分布式文件平臺。
那么文件是怎么序列化為流數據分裝在HTTP報文中的哪?
其實我們的文件上傳怎么都要經歷如下鏈路:
1、瀏覽器解析文件,打包成數據流。
2、通過管道和服務器連接,通過http傳輸數據到后臺。
3、java程序(也可能是其他程序)做IO處理,做文件寫操作。

瀏覽器上傳文件原理

<form action="servlet/UploadFile" method="post"enctype="multipart/form-data"><input type="file" name="fileUpload" id="fileUpload" /><input type="submit" value="上傳" /></form>

enctype:屬性規定在發送到服務器之前應該如何對表單數據進行編碼。

form表單中enctype屬性可以用來控制對表單數據的發送前的如何進行編碼,
enctype有三種,分別為:
multipart/form-data不對字符編碼,用于發送二進制的文件,其他兩種類型不能用于發送文件;

text/plain用于發送純文本內容,空格轉換為 “+” 加號,不對特殊字符進行編碼,一般用于email之類的;

application/x-www-form-urlencoded,在發送前會編碼所有字符,即在發送到服務器之前,所有字符都會進行編碼(空格轉換為 “+” 加號,"+"加號轉換為空格,特殊符號轉換為 ASCII HEX 值)。

其中application/x-www-form-urlencoded為默認類型。

看下文件上傳的報文,就這么一個file控件,以CSDN上傳頭像為例,瀏覽器會自動把上傳文件解析如下:

Request URL: https://me.csdn.net/api/user/uploadBase64Avatar
Request Method: POST
Status Code: 200
Remote Address: 39.96.132.69:443
Referrer Policy: unsafe-url
access-control-allow-credentials: true
access-control-allow-headers: Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,X-Data-Type,X-Requested-With
access-control-allow-methods: GET,PUT,POST,DELETE,OPTIONS
access-control-allow-origin: https://i.csdn.net
content-type: application/json; charset=UTF-8
date: Sun, 13 Oct 2019 09:26:34 GMT
server: openresty
status: 200
Provisional headers are shown
Accept: application/json, text/javascript, /; q=0.01
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryV5ocEPiRQuRh2vcB
Origin: https://i.csdn.net
Referer: https://i.csdn.net/
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
avatar_file: (binary)
a:

最下面是POST請求封裝的Form Data,我們會發現瀏覽器有自動把數據解析成二進制的數據的功能。
具體數據如下:
------WebKitFormBoundaryV5ocEPiRQuRh2vcB
Content-Disposition: form-data; name=“avatar_file”; filename=“avatar_file.png”
Content-Type: image/png

‰PNG

IHDR––<qa IDATx^ì?”]gy.ü|??}z?3]ó$?z±%[–{?á—?6?òJn? —rC
……………………………………………………
------WebKitFormBoundaryV5ocEPiRQuRh2vcB
Content-Disposition: form-data; name=“a”

------WebKitFormBoundaryV5ocEPiRQuRh2vcB–

中間內容省略

二、服務器
1.服務器端程序收到"multipart/form-data"類型的http請求消息
2.讀取這個請求消息里面的實體內容
3.解析每個分區的數據
4.從每個分區中解析出描述頭和主體內容部分

@RequestMapping("/uploadFile")public void uploadFile(HttpServletRequest request, HttpServletResponse response) {ProgressListener progressListener = new ProgressListener() {@Overridepublic void update(long l, long l1, int i) {}};String savePath = "D:\\faceImage\\";File file = new File(savePath);if (!file.exists() && file.isDirectory()) {System.out.println(savePath + "目錄不存在,需要創建");file.mkdir();}try {DiskFileItemFactory factory = new DiskFileItemFactory();ServletFileUpload upload = new ServletFileUpload(factory);upload.setHeaderEncoding("UTF-8");if (!ServletFileUpload.isMultipartContent(request)) {//}upload.setProgressListener(progressListener);List<FileItem> fileItemList = upload.parseRequest(request);fileItemList.forEach(item -> {if (item.isFormField()) {//普通的參數對應的讀取String name = item.getFieldName();try {String value = item.getString("UTF-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}} else {//如果fileupload中是上傳文件String fileName = item.getName();if (fileName == null || fileName.trim().equals("")) {return;}if (fileName.contains("\\")) {fileName = fileName.substring(fileName.lastIndexOf("\\" + 1));}try {InputStream inputStream = item.getInputStream();FileOutputStream fileOutputStream = new FileOutputStream(savePath + "\\" + fileName);byte[] buffer = new byte[1024];int len = 0;while ((len = inputStream.read(buffer)) > 0) {fileOutputStream.write(buffer);}inputStream.close();fileOutputStream.close();} catch (IOException e) {e.printStackTrace();}}});} catch (Exception e) {e.printStackTrace();}}

總結

以上是生活随笔為你收集整理的http上传文件原理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。