久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

IE瀏覽器下載文件中文文件名亂碼問題解決

 忠波irlphwt1ng 2019-12-02

處理過程

根據(jù)IE的F12中的log提示,是因?yàn)閔ttp頭信息中的編碼替換了html文件中的編碼,。我最初的思路是設(shè)置Tomcat默認(rèn)編碼,,但是我發(fā)現(xiàn)我已經(jīng)在Server.xml中設(shè)置過,想到這里我想到了上篇文章的文件重命名的問題,,準(zhǔn)備去寫個(gè)filter去修改http響應(yīng)頭,,但是我突然明白,SpringMVC應(yīng)該會(huì)處理過,,但是為什么無效呢,,這種成熟的框架不應(yīng)該會(huì)有bug存在,于是我嘗試在SpringMVC的xml中配置SourceHttpMessageConverter等轉(zhuǎn)換器,,都無效,。

發(fā)現(xiàn)原因

后來發(fā)現(xiàn)web.xml是配置了編碼處理的, 內(nèi)容如下:

  1. //第一個(gè)工具類中的下載方法:
  2. /**
  3. * 下載
  4. * @param request
  5. * @param response
  6. * @param fileName
  7. * @param downLoadPath
  8. * @param contentType
  9. * @throws IOException
  10. * @throws Exception
  11. */
  12. public static void download(HttpServletRequest request,HttpServletResponse response,String fileName,String downLoadPath,String contentType) throws IOException{
  13. response.setContentType("text/html;charset=UTF-8");
  14. request.setCharacterEncoding("UTF-8");
  15. BufferedInputStream bis = null;
  16. BufferedOutputStream bos = null;
  17. long fileLength = new File(downLoadPath).length();
  18. response.setContentType(contentType);
  19. response.setHeader("Content-disposition", "attachment; filename=" + new String(fileName.getBytes("utf-8"), "ISO8859-1"));
  20. response.setHeader("Content-Length", String.valueOf(fileLength));
  21. bis = new BufferedInputStream(new FileInputStream(downLoadPath));
  22. bos = new BufferedOutputStream(response.getOutputStream());
  23. byte[] buff = new byte[2048];
  24. int bytesRead;
  25. while(-1 != (bytesRead = bis.read(buff, 0, buff.length))){
  26. bos.write(buff, 0, bytesRead);
  27. }
  28. bis.close();
  29. bos.close();
  30. }
  31. //第二個(gè)工具類中的主要關(guān)鍵代碼:
  32. String filename = null;
  33. if(request.getHeader("User-Agent").toUpperCase().indexOf("MSIE") > 0){
  34. filename = URLEncoder.encode(name, "UTF-8");
  35. }else{
  36. filename = new String(name.getBytes(),"ISO8859-1");
  37. }
  38. response.setHeader("Content-Disposition", "attachment;filename=" + filename);

為了知道這樣子到底會(huì)有什么問題,,是不是只有IE會(huì)出現(xiàn)問題,,其他瀏覽器會(huì)不會(huì)有其他的問題,。抱著這些疑問,我找來了目前市面上用戶量較多的幾款主流的瀏覽器進(jìn)行測(cè)試,,包括:兩個(gè)不同版本的IE11,,Chrome,F(xiàn)ireFox,,Opera,,360瀏覽器,搜狗瀏覽器等,。經(jīng)過我對(duì)下載的文件的各種文件名稱使勁地折騰主要發(fā)現(xiàn)以下幾個(gè)問題: 
1.兩個(gè)IE11在使用第一個(gè)方法下載文件時(shí)中文文件名都會(huì)亂碼,,而使用第二個(gè)方法下載時(shí)其中一個(gè)IE11中文不會(huì)亂碼,另一個(gè)IE11則會(huì)亂碼,; 
2.文件名中存在空格時(shí)兩個(gè)IE11瀏覽器下載下來文件文件名空格會(huì)變成+號(hào),,其他瀏覽器沒有這個(gè)問題; 
3.火狐瀏覽器下載時(shí)遇到文件名中有空格時(shí)下載下來的文件的文件名第一個(gè)空格后面的文字都會(huì)丟失,。 
經(jīng)過一番折騰發(fā)現(xiàn)原來我們大國產(chǎn)瀏覽器還是可以的,,沒有發(fā)現(xiàn)明顯的問題;233333,。 
那么這些問題該如何解決呢,?首先第一個(gè)問題,顯然第一段代碼并沒有將IE瀏覽器過濾出來對(duì)文件名進(jìn)行單獨(dú)編碼,,而是統(tǒng)一采用ISO8859-1編碼,,這樣如果文件名是英文的IE就不會(huì)出現(xiàn)任何問題,中文就會(huì)出現(xiàn)亂碼,,其他語言文字則不清楚,,其他幾款瀏覽器則沒有任何問題,都能兼容,。那第二段代碼則首先對(duì)Http請(qǐng)求頭中User-Agent參數(shù)進(jìn)行了判斷,,通過MISE字段將IE瀏覽器過濾出來,對(duì)文件名進(jìn)行單獨(dú)UTF-8編碼,,所以中文文件名不會(huì)亂碼了,。那么問題來了,為什么兩個(gè)IE11瀏覽器,,其中一個(gè)中文不亂碼,,而另一個(gè)卻亂碼呢。經(jīng)過對(duì)程序的單步調(diào)試,,發(fā)現(xiàn)那個(gè)中文亂碼的IE在進(jìn)入這個(gè)方法后程序并沒有跳入對(duì)文件名進(jìn)行utf-8編碼的方法,,而是進(jìn)入了else下面的那一行代碼。那也就是說兩個(gè)IE11的User-Agent參數(shù)中,其中一個(gè)有MISE關(guān)鍵字,,而另一個(gè)則沒有,。通過查閱資料,原來微軟在IE11之后在瀏覽器的User-Agent參數(shù)中去掉了MISE關(guān)鍵字,,導(dǎo)致的結(jié)果是使用低版本的IE下載中文文件名文件時(shí)不會(huì)亂碼,,而采用大部分IE11及以上版本,包括Edge等都會(huì)出現(xiàn)中文亂碼現(xiàn)象,。難怪大家老是說IE很坑呢,,IE在這種地方都埋好了坑,,等著我們?nèi)ゲ?,我也是醉了?nbsp;
瀏覽器的User-Agent這個(gè)參數(shù)主要包含了一些操作系統(tǒng)版本,瀏覽器版本,、內(nèi)核等信息,。 
那個(gè)下載文件中文會(huì)亂碼的IE的User-Agent參數(shù)如下: 
IE11:Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko; 
顯然里面并沒有MISE關(guān)鍵字,,那么怎么辦呢,?通過對(duì)比幾款不同瀏覽器的User-Agent參數(shù),發(fā)現(xiàn)這里面有一個(gè)Trident關(guān)鍵字比較特別,,是其他瀏覽器所沒有的,,那么解決方案來了,我們可以通過Trident關(guān)鍵字來進(jìn)行對(duì)部分IE11的過濾了,; 
那么針對(duì)第二個(gè)問題中出現(xiàn)的空格變+號(hào),,則是因?yàn)閁RLEncoder函數(shù)在對(duì)字符串進(jìn)行轉(zhuǎn)碼后將空格替換成了+號(hào),IE就直接把+號(hào)顯示出來了,,解決方法是在對(duì)文件名進(jìn)行轉(zhuǎn)碼后,,使用replace方法將+號(hào)替換為%20即可,瀏覽器會(huì)將%20轉(zhuǎn)換成空格輸出,。 
對(duì)于第三個(gè)問題則是因?yàn)榇a在set響應(yīng)頭時(shí)Content-Disposition參數(shù)的attachment;filename=等號(hào)后面文件名字符串沒有用雙引號(hào)括起來,,火狐瀏覽器對(duì)于遇到文件名有空格時(shí)認(rèn)為空格前的字符是一個(gè)完整的字符串,故下載下來文件時(shí)文件名就只剩下空格前的那幾個(gè)字了,。解決方法是在filename兩邊加上雙引號(hào)并加反斜杠轉(zhuǎn)義,。具體的最終解決這些問題后經(jīng)過測(cè)試兼容性比較好的代碼如下:

  1. public static void download(HttpServletRequest request, HttpServletResponse response, String fileName, String downLoadPath, String contenType) throws Exception {
  2. response.setContentType("text/html;charset=UTF-8");
  3. request.setCharacterEncoding("UTF-8");
  4. BufferedInputStream bis = null;
  5. BufferedOutputStream bos = null;
  6. long fileLength = new File(downLoadPath).length();
  7. response.setContentType(contenType);
  8. String header = request.getHeader("User-Agent").toUpperCase();
  9. if (header.contains("MSIE") || header.contains("TRIDENT") || header.contains("EDGE")) {
  10. fileName = URLEncoder.encode(fileName, "utf-8");
  11. fileName = fileName.replace("+", "%20"); //IE下載文件名空格變+號(hào)問題
  12. } else {
  13. fileName = new String(fileName.getBytes(), "ISO8859-1");
  14. }
  15. response.setHeader("Content-disposition", "attachment; filename=\"" + fileName + "\"");
  16. response.setHeader("Content-Length", String.valueOf(fileLength));
  17. bis = new BufferedInputStream(new FileInputStream(downLoadPath));
  18. bos = new BufferedOutputStream(response.getOutputStream());
  19. byte[] buff = new byte[2048];
  20. int bytesRead;
  21. while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
  22. bos.write(buff, 0, bytesRead);
  23. }
  24. bis.close();
  25. bos.close();
  26. }

或者,使用下面這段代碼也可以處理亂問題,,代碼如下:

  1. try {
  2. String fileName = attachmentFile.originalName();
  3. String userAgent = request.getHeader("user-agent").toLowerCase();
  4. if (userAgent.contains("msie") || userAgent.contains("like gecko") ) {
  5. // win10 ie edge 瀏覽器 和其他系統(tǒng)的ie
  6. fileName = URLEncoder.encode(fileName, "UTF-8");
  7. } else {
  8. //其他的瀏覽器
  9. fileName = new String(fileName.getBytes("utf-8"), "iso-8859-1");
  10. }
  11. response.setCharacterEncoding("utf-8");
  12. response.setContentType("multipart/form-data");
  13. response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
  14. String path = attachmentFile.path();
  15. InputStream inputStream = new FileInputStream(new File(path));
  16. OutputStream os = response.getOutputStream();
  17. byte[] b = new byte[2048];
  18. int length;
  19. while ((length = inputStream.read(b)) > 0) {
  20. os.write(b, 0, length);
  21. }
  22. // 這里主要關(guān)閉流,。
  23. os.close();
  24. inputStream.close();
  25. } catch (FileNotFoundException e) {
  26. e.printStackTrace();
  27. } catch (IOException e) {
  28. e.printStackTrace();
  29. }

 

本文轉(zhuǎn)載別人文章,有侵權(quán)什么問題,,聯(lián)系及時(shí)處理,。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多