使用Python原生地處理multipart/form-data

image.png

RFC7578(淘汰了RFC2388)定義了multipart/form-data類型寨蹋,當(dāng)用戶在Web頁面上提交表單時(shí),這種數(shù)據(jù)類型通常通過HTTP進(jìn)行傳輸丈攒。如今褥实,它往往被JSON編碼的payload(負(fù)載)所取代;盡管如此遍希,它仍然被廣泛使用等曼。

雖然你可以用Python原生解碼使用JSON創(chuàng)建的HTTP主體請(qǐng)求(這多虧了JSON模塊),但是對(duì)于multipart/form-data卻沒有這樣的方法孵班∩媸蓿考慮到這種格式的歷史悠久,這幾乎是難以理解的篙程。

有很多種方法可以對(duì)這種格式進(jìn)行編碼和解碼。像requests之類的庫在不引起你注意的情況下已經(jīng)原生地支持這種特性别厘,大多數(shù)Web服務(wù)器框架(比如Django或Flask)也是如此虱饿。

然而,在某些情況下触趴,你可能需要自己對(duì)這種格式進(jìn)行編碼或解碼氮发。在這些情況下,通過添加外部依賴來處理編解碼冗懦,不是一個(gè)可接受的選項(xiàng)(比如嵌入式設(shè)備上沒有網(wǎng)爽冕,無法pip)。

編碼

multipart/form-data格式非常容易理解披蕉,可以概括為一種編碼鍵和值列表的簡單方法颈畸,即,一種可移植的序列化字典的方法没讲。

Python中沒有任何東西可以生成這樣的編碼眯娱。這種格式非常簡單,由鍵和值組成爬凑,并由一個(gè)隨機(jī)的邊界分隔符包圍徙缴。分隔符必須作為 Content-Type的一部分進(jìn)行傳遞,以便解碼器能夠解碼表單數(shù)據(jù)嘁信。

urllib3中有完成這項(xiàng)工作的一個(gè)簡單實(shí)現(xiàn)于样。我們?cè)谶@個(gè)簡單的實(shí)現(xiàn)中對(duì)它總結(jié)一下:

使用Python原生地處理multipart/form-data

你可以通過傳遞一個(gè)字典來使用這種格式,其中鍵和值都是字節(jié)潘靖。例如:

使用Python原生地處理multipart/form-data

它會(huì)返回:

使用Python原生地處理multipart/form-data

你可以在HTTP應(yīng)答頭部Content-Type中使用返回的內(nèi)容類型穿剖。注意,這種格式是用于表單的:它也可以用于電子郵件秘豹。

你說的是電子郵件嗎?

使用email進(jìn)行編碼

是的携御,電子郵件通常是使用MIME編碼的,MIME由另一個(gè)RFC—RFC2046—定義。事實(shí)證明啄刹,multipart/form-data只是一種特殊的MIME格式涮坐,如果你有實(shí)現(xiàn)MIME處理的代碼,那么使用它來實(shí)現(xiàn)這種格式是很容易的誓军。

對(duì)我們來說幸運(yùn)的是袱讹,Python標(biāo)準(zhǔn)庫附帶了一個(gè)模塊,該模塊可以處理它:email.mime昵时。我告訴過你它被電子郵件大量使用—我猜這就是為什么他們會(huì)把處理代碼放在email子包中捷雕。

這里有一段代碼,它使用幾行代碼來處理multipart/form-data :

使用Python原生地處理multipart/form-data

使用這段代碼會(huì)返回以下結(jié)果:

使用Python原生地處理multipart/form-data

與我們的第一個(gè)實(shí)現(xiàn)相比壹甥,這個(gè)方法有幾個(gè)優(yōu)點(diǎn):

  • 它為每個(gè)添加的MIME部分處理Content-Type救巷。我們可以添加其他數(shù)據(jù)類型,而不僅僅是text/plain句柠,就像在第一個(gè)版本中顯式所做的那樣浦译。我們還可以指定文本數(shù)據(jù)的字符集(編碼方式)。
  • 通過使用經(jīng)過廣泛測(cè)試的Python標(biāo)準(zhǔn)庫溯职,它很可能會(huì)更加健壯精盅。

在這種情況下,主要的缺點(diǎn)是內(nèi)容中包含了Content-Type頭部谜酒。在處理HTTP時(shí)叹俏,這是有問題的,因?yàn)檫@需要作為HTTP頭部的一部分被發(fā)送僻族,而不是作為負(fù)載的一部分粘驰。

從email.generator構(gòu)建一個(gè)完成這一任務(wù)的特定的生成器是可能的。我將把它留給你們做練習(xí)鹰贵,讀者們晴氨。

解碼

我們必須能夠使用相同的 email 包來解碼我們的編碼數(shù)據(jù),對(duì)嗎?事實(shí)證明是這樣的碉输,我們可以通過一段這樣的代碼來實(shí)現(xiàn):

使用Python原生地處理multipart/form-data

使用上面的示例數(shù)據(jù)籽前,這段代碼會(huì)返回:

使用Python原生地處理multipart/form-data

超級(jí)棒,對(duì)嗎敷钾?

這個(gè)故事的寓意是枝哄,你永遠(yuǎn)不要低估標(biāo)準(zhǔn)庫的威力。雖然在你的依賴項(xiàng)列表中添加一行代碼很容易阻荒,但是如果你深入研究一下Python為你提供了什么挠锥,你會(huì)發(fā)現(xiàn)你并不總是需要這樣做!

英文原文:https://julien.danjou.info/handling-multipart-form-data-python/

譯者:野生大熊貓
注:我這有個(gè)學(xué)習(xí)Python基地,里面有很多學(xué)習(xí)資料侨赡,感興趣的+Q群:895817687

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蓖租,一起剝皮案震驚了整個(gè)濱河市粱侣,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蓖宦,老刑警劉巖齐婴,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異稠茂,居然都是意外死亡柠偶,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門睬关,熙熙樓的掌柜王于貴愁眉苦臉地迎上來诱担,“玉大人,你說我怎么就攤上這事电爹∧柘桑” “怎么了?”我有些...
    開封第一講書人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵藐不,是天一觀的道長匀哄。 經(jīng)常有香客問我,道長雏蛮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任阱州,我火速辦了婚禮挑秉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘苔货。我一直安慰自己犀概,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開白布夜惭。 她就那樣靜靜地躺著姻灶,像睡著了一般。 火紅的嫁衣襯著肌膚如雪诈茧。 梳的紋絲不亂的頭發(fā)上产喉,一...
    開封第一講書人閱讀 50,050評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音敢会,去河邊找鬼曾沈。 笑死,一個(gè)胖子當(dāng)著我的面吹牛鸥昏,可吹牛的內(nèi)容都是我干的塞俱。 我是一名探鬼主播,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼吏垮,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼障涯!你這毒婦竟也來了罐旗?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤唯蝶,失蹤者是張志新(化名)和其女友劉穎九秀,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體生棍,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡颤霎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了涂滴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片友酱。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖柔纵,靈堂內(nèi)的尸體忽然破棺而出缔杉,到底是詐尸還是另有隱情,我是刑警寧澤搁料,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布或详,位于F島的核電站,受9級(jí)特大地震影響郭计,放射性物質(zhì)發(fā)生泄漏霸琴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一昭伸、第九天 我趴在偏房一處隱蔽的房頂上張望梧乘。 院中可真熱鬧,春花似錦庐杨、人聲如沸选调。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽仁堪。三九已至,卻和暖如春填渠,著一層夾襖步出監(jiān)牢的瞬間弦聂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來泰國打工揭蜒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留横浑,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓屉更,卻偏偏與公主長得像徙融,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子瑰谜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容

  • 網(wǎng)絡(luò) 理論模型,分為七層物理層數(shù)據(jù)鏈路層傳輸層會(huì)話層表示層應(yīng)用層 實(shí)際應(yīng)用,分為四層鏈路層網(wǎng)絡(luò)層傳輸層應(yīng)用層 IP...
    FlyingLittlePG閱讀 762評(píng)論 0 0
  • Python語言特性 1 Python的函數(shù)參數(shù)傳遞 看兩個(gè)如下例子欺冀,分析運(yùn)行結(jié)果: 代碼一: a = 1 def...
    伊森H閱讀 3,054評(píng)論 0 15
  • # Python 資源大全中文版 我想很多程序員應(yīng)該記得 GitHub 上有一個(gè) Awesome - XXX 系列...
    小邁克閱讀 2,967評(píng)論 1 3
  • 目錄:主要從一個(gè)“你的思維決定結(jié)果”問題開始树绩,衍生到你如何被思維影響,到怎么去緩解思維對(duì)你的困擾隐轩,到如何去解決并控...
    玦_fe95閱讀 598評(píng)論 0 1
  • 經(jīng)常走路去送兒子上學(xué)饺饭,家離學(xué)校很近,走路也就是六职车、七分鐘的路程瘫俊,不是我自己喜歡走路而是我喜歡和兒子一起走。...
    佳慧佳圻媽媽閱讀 225評(píng)論 0 0