jquery file upload 後臺收到的文件名中文亂碼, filename中文亂碼

原文鏈接:http://blog.csdn.net/zhouyingge1104/article/details/38322403


本週用jQuery file upload做上傳文件的功能,後臺會接受文件,並且截取文件名作爲字符存入數據庫。基本功能實現時候,試了幾個文件,發現如果文件名如果沒有中文就OK,如果文件名帶中文的話,後臺收到的就是中文亂碼,怎麼去解碼都沒用。

例如,上傳的文件叫做“昕銳配置表.xls”,但是到後臺收到的卻是 “鏄曢攼閰嶇疆琛?xls” ,如下圖:


似乎也不是解碼能解決的問題。

於是乎想弄清楚這個文件名是在哪個環節出問題的。首先寫了一個最簡單的html頁面,裏面就是最原始的FORM表單,然後提交後臺,發現一切正常,文件名是對的,因此大概可以判斷和後臺無關,很可能就是jquery file upload這個插件的問題。

於是,用http工具觀察了一下上傳文件時傳輸的信息,發現如下問題,主要是POSTDATA部分的Content-Disposition中的filename部分:

原生的FROM提交時,這個filename是正常的:



而用jquery file upload這個插件提交時,這個filename就已經亂了:



於是乎,已經成功地定位了問題產生的環節,就是在jquery file upload這個插件的問題。估計是這個插件的作者沒怎麼考慮字符編碼的問題。

關於JavaScript的字符編碼問題,好像曾經也接觸過一點,好像是類似於 encodeURI() 或者 encodeURICompent() 這些方法。不過,現在首要的任務是找出jquery.fileupload.js這個文件中是哪一步設置了 filename 這個參數。

整整兩天,測試來測試去,最終找到了這個地方:這個js中有個成員叫做 _initXHRData, 是一個function, 在這個function的最後部分有一個if-else分支,如下:

  1. if (options.blob) {  
  2.                         formData.append(paramName, options.blob, file.name);  
  3.                     } else {  
  4.                         $.each(options.files, function (index, file) {  
  5.                             // This check allows the tests to run with  
  6.                             // dummy objects:  
  7.                             if (that._isInstanceOf('File', file) ||  
  8.                                     that._isInstanceOf('Blob', file)) {                                       
  9.                                 formData.append(  
  10.                                     ($.type(options.paramName) === 'array' &&  
  11.                                         options.paramName[index]) || paramName,  
  12.                                     file,  
  13.                                     file.uploadName || file.name  
  14.                                 );  
  15.                             }  
  16.                         });  
  17.                     }  
if (options.blob) {
                        formData.append(paramName, options.blob, file.name);
                    } else {
                        $.each(options.files, function (index, file) {
                            // This check allows the tests to run with
                            // dummy objects:
                            if (that._isInstanceOf('File', file) ||
                                    that._isInstanceOf('Blob', file)) {										
                                formData.append(
                                    ($.type(options.paramName) === 'array' &&
                                        options.paramName[index]) || paramName,
                                    file,
                                    file.uploadName || file.name
                                );
                            }
                        });
                    }

實際測試表明,程序會進入else這個分支,並且,else分支中的最後一步,也就是formData.append()這個方法中會對 filename 進行設置,具體的值就是最後一行的

  1. file.uploadName || file.name  
file.uploadName || file.name

很顯然,這裏並沒有對這個文件名做任何編碼處理,發送出去確實容易導致編碼的問題。因此,就在這裏用encodeURI()方法做一下處理:

  1. encodeURI(file.uploadName || file.name)  
encodeURI(file.uploadName || file.name)

然後再次測試,這次發送的http信息中的filename就變成了進行編碼處理過的字符串:



然後在後臺,用java.net.URLDecoder進行解碼:

  1. fileName = URLDecoder.decode(fileDetail.getFileName(), "UTF-8");  
fileName = URLDecoder.decode(fileDetail.getFileName(), "UTF-8");

OK,正確輸出:

這個插件導致的中文亂碼問題終於搞定,花了整整4天了!


總結:很多問題看上去完全是無從下手,但仔細想想,其實我們手上有很多實用的工具,我們要做的就是利用好這些工具,抓住每一點蛛絲馬跡,堅信沒有解決不了的技術問題,一步一步進行推導,最終找到問題的根源,並加以解決。

所謂解決不了的技術問題,多半是因爲對這些技術以及相關的知識不夠熟悉罷了。只要相關的知識夠豐富,經驗夠多,解決特定的問題會很輕鬆。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章