天天看點

Django - 檔案上傳下載下傳

一般的, 上傳可以分為通過form表單送出和通過ajax送出兩種。

沒麼多事兒,來看示例:

前端重要代碼。

一般的,在普通的form表單送出時,請求頭中的<code>CONTENT_TYPE: application/x-www-form-urlencoded</code>,然後資料是以鍵值對的形式傳輸的,服務端從<code>request.POST</code>取值,這沒問題,并且<code>CONTENT_TYPE: application/x-www-form-urlencoded</code>這種編碼類型滿足大多數情況,一切都挺好的。

而要說使用form表單上傳檔案,就不得不多說兩句了。

起初,http 協定中沒有上傳檔案方面的功能,直到 rfc1867 為 http 協定添加了這個功能。當然在 rfc1867 中限定 <code>form</code>标簽的 <code>method</code> 必須為 <code>POST</code>,<code>enctype = "multipart/form-data"</code> 以及<code>&lt;input type = "file"&gt;</code>。

是以,當使用form表單上傳檔案的時候,請求頭的<code>content_type</code>是<code>multipart/form-data</code>這種形式的,是以,我們需要在form标簽添加<code>enctype="multipart/form-data</code>屬性來進行辨別。

如果你能列印上傳檔案的請求頭,你會發現<code>CONTENT_TYPE</code>是這樣的<code>content_type:multipart/form-data; boundary=----WebKitFormBoundarylZZyJUkrgm6h34DU</code>,那<code>boundary=----WebKitFormBoundarylZZyJUkrgm6h34DU</code>又是什麼呢?

在<code>multipart/form-data</code> 後面有<code>boundary</code>以及一串字元,這是分界符,後面的一堆字元串是随機生成的,目的是防止上傳檔案中出現分界符導緻伺服器無法正确識别檔案起始位置。那分界符又有啥用呢?

對于上傳檔案的post請求,我們沒有使用原有的 http 協定,是以 multipart/form-data 請求是基于 http 原有的請求方式 post 而來的,那麼來說說這個全新的請求方式與 post 的差別:

請求頭的不同,對于上傳檔案的請求,<code>contentType = multipart/form-data</code>是必須的,而 post 則不是,畢竟 post 又不是隻上傳檔案~。

請求體不同,這裡的不同也就是指前者(上傳檔案請求)在發送的每個字段内容之間必須要使用分界符來隔開,比如檔案的内容和文本的内容就需要分隔開,不然伺服器就沒有辦法正常的解析檔案,而後者 post 當然就沒有分界符直接以<code>key:value</code>的形式發送就可以了。

當然,其中的彎彎繞繞不是三言兩語能解釋的清楚的,我們先知道怎麼用就行。

再來看views視圖處理:

前端檔案:

在 ajax 中 contentType 設定為 false 是為了避免 JQuery 對請求頭<code>content_type</code>進行操作,進而失去分界符,而使伺服器不能正常解析檔案。

在使用jQuery的$.ajax()方法的時候參數processData預設為true(該方法為jQuery獨有的),預設情況下會将發送的資料序列化以适應預設的内容類型application/x-www-form-urlencoded

如果想發送不想轉換的資訊的時候需要手動将其設定為false即可。

再來看後端<code>views.py</code>如何處理:

OK了,多說無益,幹就完了。

下載下傳

views中主要代碼:

如果你細心的嘗試,會發現,上面兩中下載下傳方式中的<code>filename</code>不能包含中文,那麼如何解決呢?來,往下看!

是不是解決了!完美!!