變更紀錄
每個版本都會註明它跟隨的 Chromium 版本。跟隨較新 Chromium 版本的發布,即使 API 沒變,凡是 Chromium 改了規則的地方,回傳的檔名也可能不同。
0.2.0
- 跟 0.1.0 一樣,跟隨 Chromium
dfd5cca812cefda32e909ae39965ed22041d5e65(main,2026-10-16)及其 ICU 78。 suggested_filename()改為接受回應的整組標頭,並照 Chrome 的方式從中推導 MIME 類型(但不檢查內容);新增的sanitize_filename()可以清洗任何來源的名稱。為 0.1.0 寫的呼叫可能需要下列修改。
不相容的改動
| 0.1.0 | 0.2.0 |
|---|---|
suggested_filename(url) |
suggested_filename(url=url) |
suggested_filename(url, header) |
suggested_filename(url=url, content_disposition=header) |
suggested_filename(None, header) |
suggested_filename(content_disposition=header) |
suggested_filename(url, suggested_name=name) |
suggested_filename(url=url, download_attribute=name) |
suggested_filename(url, mime_type=content_type) |
suggested_filename(url=url, content_type=content_type) |
suggested_filename(url, default_name="") |
suggested_filename(url=url, default_name=None) |
在 Windows 上執行的 suggested_filename(url=url, content_disposition=header) |
suggested_filename(url=url, content_disposition=header, platform="posix") |
parse_content_disposition(value=header) |
parse_content_disposition(header) |
suggested_filename()只有一個引數能以位置傳入,就是新的headers,而它不能是字串或位元組:以位置傳入網址或標頭會丟出TypeError。suggested_name改名為download_attribute;mime_type改名為content_type,它是伺服器送出的原樣 Content-Type 標頭(見〈行為改動〉)。default_name=None表示改用網址的主機名稱。0.1.0 用空字串的default_name表示這件事,0.2.0 則會丟出ValueError。platform的預設值改為None:在 Windows 上執行時採用 Windows 的規則,在其他系統上採用 POSIX 的規則。0.1.0 在任何系統上都採用 POSIX 的規則;在 Windows 上要得到跟它相同的檔名,就傳入platform="posix"。parse_content_disposition()的value只能以位置傳入。
要改傳回應的整組標頭、而不是單一個標頭,見使用方式。
新功能
suggested_filename(headers, url=...)接受回應的標頭:mapping,或由(名稱, 值)配對組成的 iterable,值是字串或位元組(型別是HeadersLike,可以匯入來標註型別)。第一行 Content-Disposition 的第一個值決定檔名,各行 Content-Type 與 X-Content-Type-Options 決定 MIME 類型。content_disposition和content_type不是None時,會取代這些行。parse_content_disposition()也接受回應的整組標頭,結果多了一個欄位blocks_download:Chrome 是否因為 Content-Disposition 的值(在引號外的逗號處切開)不全相同,或標頭裡有 NUL,而拒絕這個回應。suggested_filename()照樣用第一個值決定檔名。這個欄位參與相等比較,也出現在 repr 裡:attachment; filename=a,b.txt的結果不再等於ContentDisposition("attachment", "a")。headers_encoding指定你的 HTTP 函式庫解碼標頭時用的 codec,例如 requests 和urllib.request是"latin-1",用來把每一個字串形式的標頭值精確還原成解碼前的位元組。content_type也接受位元組。sanitize_filename()清洗任何來源的名稱,例如網頁標題,清洗方式跟 Chrome 清洗<a download>的值相同。- 使用方式示範了怎麼從 httpx2、httpx、requests、aiohttp 和
urllib.request傳入標頭,測試也會用這些函式庫實際取回回應來檢查。
行為改動
有些呼叫在 0.2.0 會得到不同的結果,分成三類。
更接近 Chromium。
- 每一個標頭值,包括
content_disposition、content_type和parse_content_disposition()的value,都當成該行標頭照送出時原樣的其餘部分來讀(見讀取標頭行):以空白或 tab 開頭的行用一個空白接上,其他的行或空行則結束這個值。0.1.0 把 CR 和 LF 當成值裡的字元:attachment;\r\n filename=wire.pdf得不到檔名,attachment; filename=a.pdf\r\nX-Note: 1則把下一行也吞進檔名;0.2.0 分別得到wire.pdf和a.pdf。不含 CR 或 LF 的值不受這項改動影響。 content_type照 Chrome 網路層讀 Content-Type 標頭的方式來讀(見 MIME 類型):類型到第一個空白、tab、;或(為止;有好幾個以逗號分隔的值時,最後一個有類型的值勝出,*/*這個值本身則不改變結果。所以網址是https://example.com/page時,text/html(comment)、text/html charset=utf-8和text/plain, text/html都得到page.html,0.1.0 則是page。- feed 類型
application/rss+xml和application/atom+xml跟 Chrome 一樣當成text/plain:得到page.txt,0.1.0 則分別是page.rss和page。 - Chrome 只對
http:、https:、file:和filesystem:網址檢查內容來決定 MIME 類型。網址是其他 scheme 的合法網址時,例如ftp://example.com/page,沒有給出類型的content_type(例如空字串)就是text/plain:得到page.txt,0.1.0 則是page。
content_type 是原樣的標頭。 0.1.0 的文件說,伺服器沒有送出 X-Content-Type-Options: nosniff 時,要傳入 Chrome 會用的 MIME 類型,因為 Chrome 這時可能檢查內容、改用別的類型。0.2.0 撤回這個建議:content_type 是伺服器送出的原樣 Content-Type 標頭;Chrome 會檢查內容時,本套件看不到內容,用的是標頭宣告的類型。以來自 https://example.com/page、沒有 Content-Type、內容是 HTML 的回應為例,照舊的建議要傳 mime_type="text/html",得到 page.html;0.2.0 對這組標頭給出 page,而 Chrome 回報的是 page.html(見 Chrome 檢查內容時)。
改傳整組標頭。 從傳單一個標頭改成傳全部的標頭,檔名可能改變:
X-Content-Type-Options: nosniff會算數。有它時 Chrome 不檢查內容,沒有 Content-Type、或 Content-Type 沒有給出類型的回應就是text/plain:https://example.com/page得到page.txt,0.1.0 則是page。- 每一行 Content-Type 都算數:最後一個有類型的值勝出,
*/*這個值本身則不改變結果。urllib.request和 aiohttp 依名稱取標頭時只給第一行:遇到text/plain和application/pdf兩行時,0.1.0 依第一行得到page.txt,0.2.0 依兩行得到page.pdf。 - 檔名跟以前一樣取自第一行 Content-Disposition 的第一個值。requests、httpx 和 httpx2 的
response.headers會把好幾行接成一行,結果可能跟分開的各行不同(見接成一行的標頭與推測的位元組)。
0.1.0
- 首次發布,跟隨 Chromium
dfd5cca812cefda32e909ae39965ed22041d5e65(main,2026-10-16)及其 ICU 78。 suggested_filename()回傳 Chromium 替一次下載建議的檔名,parse_content_disposition()照 Chromium 的方式讀取 Content-Disposition 標頭。兩者都接受位元組或字串形式的標頭。- 純 Python、沒有相依套件,支援 CPython 3.11 以上和 PyPy。