之前用java寫了一個檔案流輸出檔案的功能,測試細節功能的時候,發現了許多問題
一、火狐浏覽器下載下傳帶中文名字的檔案會亂碼,其他浏覽器不會
1、原因:找了下資料後發現,是火狐使用了RFC 2183協定。
檔案名存在http header中的filename,Content-Disposition: attachment; filename=FILENAME,該filename參數可用于為浏覽器下載下傳資源的檔案的名稱提供建議。但是,RFC 2183中聲明檔案名隻能使用US-ASCII字元,目前大多數流行的Web浏覽器似乎允許非US-ASCII字元(由于缺乏标準)在編碼方案和檔案名的字元集規範上不同意。那麼問題是,如果檔案名“naïvefile”(沒有引号和第三個字母是U + 00EF)需要編碼到Content-Disposition頭檔案中。
2、解決方案:是以隻需要在Content-Disposition做下處理即可:重點是filename*=utf-8'zh_cn'
byte[] source = (byte[]) result.get("exportData");
HttpServletResponse response = RequestContextHolder.getRequestAttributes().getResponse();
if (response != null) {
response.reset();
response.setHeader("Content-Disposition", "attachment;filename*=utf-8'zh_cn'" + URLEncoder.encode("導出檔案名.csv", "UTF-8"));
response.setHeader("Connection", "close");
response.setHeader("Content-Type", "application/octet-stream");
OutputStream out = response.getOutputStream();
out.write(source);
out.flush();
out.close();
}
二、ios系統safiri浏覽器導出任何類型檔案都變成dms字尾類型的檔案
原因:header請求中,Content-Type設定application/octet-stream,而該type類型對應Mime 類型清單剛好是dms字尾的檔案,是以safiri浏覽器就直接将該檔案生成為dms字尾的檔案了
解決方案:大部分浏覽器都可以使用通用類型application/octet-stream,但遇到特殊的如safiri,就最好是生成什麼類型的檔案,就傳對應的tpye
//這裡Content-Type傳對應的檔案類型,參考下面的MIME表
response.setHeader("Content-Type", "text/csv");
另附上Mime 類型清單:
擴充名 | 類型/子類型 |
---|---|
application/octet-stream | |
323 | text/h323 |
acx | application/internet-property-stream |
ai | application/postscript |
aif | audio/x-aiff |
aifc | audio/x-aiff |
aiff | audio/x-aiff |
asf | video/x-ms-asf |
asr | video/x-ms-asf |
asx | video/x-ms-asf |
au | audio/basic |
avi | video/x-msvideo |
axs | application/olescript |
bas | text/plain |
bcpio | application/x-bcpio |
bin | application/octet-stream |
bmp | image/bmp |
c | text/plain |
cat | application/vnd.ms-pkiseccat |
cdf | application/x-cdf |
cer | application/x-x509-ca-cert |
class | application/octet-stream |
clp | application/x-msclip |
cmx | image/x-cmx |
cod | image/cis-cod |
cpio | application/x-cpio |
crd | application/x-mscardfile |
crl | application/pkix-crl |
crt | application/x-x509-ca-cert |
csh | application/x-csh |
css | text/css |
dcr | application/x-director |
der | application/x-x509-ca-cert |
dir | application/x-director |
dll | application/x-msdownload |
dms | application/octet-stream |
doc | application/msword |
dot | application/msword |
dvi | application/x-dvi |
dxr | application/x-director |
eps | application/postscript |
etx | text/x-setext |
evy | application/envoy |
exe | application/octet-stream |
fif | application/fractals |
flr | x-world/x-vrml |
gif | image/gif |
gtar | application/x-gtar |
gz | application/x-gzip |
h | text/plain |
hdf | application/x-hdf |
hlp | application/winhlp |
hqx | application/mac-binhex40 |
hta | application/hta |
htc | text/x-component |
htm | text/html |
html | text/html |
htt | text/webviewhtml |
ico | image/x-icon |
ief | image/ief |
iii | application/x-iphone |
ins | application/x-internet-signup |
isp | application/x-internet-signup |
jfif | image/pipeg |
jpe | image/jpeg |
jpeg | image/jpeg |
jpg | image/jpeg |
js | application/x-javascript |
latex | application/x-latex |
lha | application/octet-stream |
lsf | video/x-la-asf |
lsx | video/x-la-asf |
lzh | application/octet-stream |
m13 | application/x-msmediaview |
m14 | application/x-msmediaview |
m3u | audio/x-mpegurl |
man | application/x-troff-man |
mdb | application/x-msaccess |
me | application/x-troff-me |
mht | message/rfc822 |
mhtml | message/rfc822 |
mid | audio/mid |
mny | application/x-msmoney |
mov | video/quicktime |
movie | video/x-sgi-movie |
mp2 | video/mpeg |
mp3 | audio/mpeg |
mpa | video/mpeg |
mpe | video/mpeg |
mpeg | video/mpeg |
mpg | video/mpeg |
mpp | application/vnd.ms-project |
mpv2 | video/mpeg |
ms | application/x-troff-ms |
mvb | application/x-msmediaview |
nws | message/rfc822 |
oda | application/oda |
p10 | application/pkcs10 |
p12 | application/x-pkcs12 |
p7b | application/x-pkcs7-certificates |
p7c | application/x-pkcs7-mime |
p7m | application/x-pkcs7-mime |
p7r | application/x-pkcs7-certreqresp |
p7s | application/x-pkcs7-signature |
pbm | image/x-portable-bitmap |
application/pdf | |
pfx | application/x-pkcs12 |
pgm | image/x-portable-graymap |
pko | application/ynd.ms-pkipko |
pma | application/x-perfmon |
pmc | application/x-perfmon |
pml | application/x-perfmon |
pmr | application/x-perfmon |
pmw | application/x-perfmon |
pnm | image/x-portable-anymap |
pot, | application/vnd.ms-powerpoint |
ppm | image/x-portable-pixmap |
pps | application/vnd.ms-powerpoint |
ppt | application/vnd.ms-powerpoint |
prf | application/pics-rules |
ps | application/postscript |
pub | application/x-mspublisher |
qt | video/quicktime |
ra | audio/x-pn-realaudio |
ram | audio/x-pn-realaudio |
ras | image/x-cmu-raster |
rgb | image/x-rgb |
rmi | audio/mid |
roff | application/x-troff |
rtf | application/rtf |
rtx | text/richtext |
scd | application/x-msschedule |
sct | text/scriptlet |
setpay | application/set-payment-initiation |
setreg | application/set-registration-initiation |
sh | application/x-sh |
shar | application/x-shar |
sit | application/x-stuffit |
snd | audio/basic |
spc | application/x-pkcs7-certificates |
spl | application/futuresplash |
src | application/x-wais-source |
sst | application/vnd.ms-pkicertstore |
stl | application/vnd.ms-pkistl |
stm | text/html |
svg | image/svg+xml |
sv4cpio | application/x-sv4cpio |
sv4crc | application/x-sv4crc |
swf | application/x-shockwave-flash |
t | application/x-troff |
tar | application/x-tar |
tcl | application/x-tcl |
tex | application/x-tex |
texi | application/x-texinfo |
texinfo | application/x-texinfo |
tgz | application/x-compressed |
tif | image/tiff |
tiff | image/tiff |
tr | application/x-troff |
trm | application/x-msterminal |
tsv | text/tab-separated-values |
txt | text/plain |
uls | text/iuls |
ustar | application/x-ustar |
vcf | text/x-vcard |
vrml | x-world/x-vrml |
wav | audio/x-wav |
wcm | application/vnd.ms-works |
wdb | application/vnd.ms-works |
wks | application/vnd.ms-works |
wmf | application/x-msmetafile |
wps | application/vnd.ms-works |
wri | application/x-mswrite |
wrl | x-world/x-vrml |
wrz | x-world/x-vrml |
xaf | x-world/x-vrml |
xbm | image/x-xbitmap |
xla | application/vnd.ms-excel |
xlc | application/vnd.ms-excel |
xlm | application/vnd.ms-excel |
xls | application/vnd.ms-excel |
xlt | application/vnd.ms-excel |
xlw | application/vnd.ms-excel |
xof | x-world/x-vrml |
xpm | image/x-xpixmap |
xwd | image/x-xwindowdump |
z | application/x-compress |
zip | application/zip |
csv | text/csv |
三、用GBK編碼還是UTF-8?
上面的問題其實還有一個原因,就是中文系統預設編碼是GBK的,是以當時生成檔案流的時候設定了GBK,但導出的時候卻用了UTF-8,是以亂碼了。必須使用統一的編碼。
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(baos, "GBK"))
...
byte[] source = baos.toByteArray();
baos.close();
return source;
byte[] source = (byte[]) result.get("exportData");
HttpServletResponse response = DataUtils.getResponse();
if (response != null) {
response.reset();
//這裡設定了utf-8,不一緻
response.setHeader("Content-Disposition", "attachment;filename*=utf-8'zh_cn'"
+ URLEncoder.encode(result.get("subject") + ".csv", "UTF-8").replace("+", "%20"));
response.setHeader("Connection", "close");
response.setHeader("Content-Type", "text/csv");
OutputStream out = response.getOutputStream();
out.write(source);
out.flush();
out.close();
}
·1、解析:
GBK是在國家标準GB2312基礎上擴容後相容GB2312的标準(好像還不是國家标準)。GBK編碼專門用來解決中文編碼的,是雙位元組的。不論中英文都是雙位元組的。
UTF-8 編碼是用以解決國際上字元的一種多位元組編碼,它對英文使用8位(即一個位元組),中文使用24位(三個位元組)來編碼。對于英文字元較多的論壇則用UTF-8 節省空間。另外,如果是外國人通路你的GBK網頁,需要下載下傳中文語言包支援。通路UTF-8編碼的網頁則不出現這問題。可以直接通路。
GBK包含全部中文字元;UTF-8則包含全世界所有國家需要用到的字元。
經常有人問網頁編寫UTF-8和GBK哪個編碼好,根據個人需要,如果你主要做中文程式的開發,客戶也主要是中國人的話就用GBK吧,因為UTF-8編碼的中文使用了三個位元組,用GBK節省了空間。
如果做英文網站開發,還是用utf-8吧,因為utf-8中英文隻占一個位元組。GBK中英文也是兩個位元組的,并且國外客戶通路GBK要下載下傳語言包。
如果你的網站是中文的,但國外使用者也不少,最好也用UTF-8的吧。
UTF-8編碼的文字可以在各國各種支援UTF8字元集的浏覽器上顯示。
比如,如果是UTF8編碼,則在外國人的英文IE上也能顯示中文,而無需他們下載下傳IE的中文語言支援包。 是以,對于英文比較多的論壇 ,使用GBK則每個字元占用2個位元組,而使用UTF-8英文卻隻占一個位元組。
UTF8是國際編碼,它的通用性比較好,外國人也可以浏覽論壇,GBK是國家編碼,通用性比UTF8差,不過UTF8占用的資料庫比GBK大。