使用Flask 編寫(xiě)建立網(wǎng)站表箭,在下載文件時(shí)如果把文件名設(shè)置為中文時(shí),在下載時(shí)會(huì)報(bào)錯(cuò)。具體代碼如下:
def get(self,*args,**kw):
fp=io.BytesIO()
self.do_get(fp,*args,**kw)
fp.seek(0)
return send_file(fp,mimetype=self.mimetype,
as_attachment=True, attachment_filename=filename)
如果attachment_filename 為英文時(shí)比肄,程序運(yùn)行正常。如為中文時(shí)囊陡,將直接報(bào)錯(cuò)芳绩。在網(wǎng)上找解決方案,會(huì)發(fā)現(xiàn)網(wǎng)上眾說(shuō)紛紜撞反,能解決問(wèn)題的沒(méi)有妥色。
后來(lái),無(wú)意中發(fā)現(xiàn)了確處理下載文件時(shí)中文文件名亂碼的問(wèn)題(Content-Disposition)遏片,這篇文章徹底解決了這個(gè)問(wèn)題嘹害。
其核心方法是應(yīng)該這樣設(shè)置 Content-Disposition:
Content-Disposition: attachment; filename="$encoded_fname" filename*=utf-8''$encoded_fname
其中,$encoded_fname指的是將 UTF-8 編碼的原始文件名按照 RFC 3986 進(jìn)行百分號(hào) urlencode 后得到的( PHP 中使用 rawurlencode()
函數(shù))吮便。
根據(jù)上述方法笔呀,可以把上面函數(shù)修改如下:
from urllib.parse import quote
def get(self,*args,**kw):
fp=io.BytesIO()
self.do_get(fp,*args,**kw)
fp.seek(0)
filename=quote(self.filename) # 對(duì)文件名進(jìn)行轉(zhuǎn)碼
rv=send_file(fp,mimetype=self.mimetype,
as_attachment=True, attachment_filename=filename)
if filename!=self.filename: # 支持中文名稱(chēng)
rv.headers['Content-Disposition']+=\
"; filename*=utf-8''%s"%(filename)
return rv
經(jīng)過(guò)上面的修改,再運(yùn)行程序髓需。當(dāng)文件名為中文的時(shí)候就可以正常下載了许师。