Anywhere you go, let me go too

關於部落格
對人海闊天空,做事仔細周密
----------------------
因為改了平台後...覺得不是很好用....所以有另外......(評估中)
http://blog.xuite.net/king119wang/myskills
  • 32543

    累積人氣

  • 2

    今日人氣

    0

    訂閱人氣

下傳接收含有中文字之檔名處理方式

        為了快速解決於是開case請MS幫忙,結果MS跟我說就在Server端將FileName做URLEncode的可以了,他說那是標準作法,想想也蠻合理的,因為我們在傳http get時,是需要針對參數值做URLEncode動作沒錯,於是跟著改,真的都解了吔!8-)

  後來還是不解為什麼在沒有URLEncode時,人家Chrome和FireFox就沒事只有你IE有事,所以我決定再去試試Chrome和FireFox , FireFox居然變成中文看不到,直接拿到的是URLEncode的內容:-O ....我開始懷疑MS的回答了(我就是這麼欠揍)

       於是開始問G博士,後來看到了幾篇文章
   無法瀏覽中文檔名網頁或下載中文檔案名稱解決方式 ==>  http://ms8.pmsh.tnc.edu.tw/~tncomu/google972/chinese.htm
           如何在瀏覽器連線 UTF-8 或 big5 中文檔名 ==>   http://www.acsite.net/tw/forum/index.php?topic=1836.0;wap2

       這兩篇讓我去思考一件事,如果在Server端針對檔名做了不是UTF8的URLEncode(檔名,Encoding.UTF7) 那會不會無法正常解析?????因為Encode和Decode編碼一定要一致才能解才對,於是開始又一連串的測試.

  將Server端的檔名做URLEncode動作,但測試各種不同編碼ANSI , UTF8,UTF7,Unicode....

        結果FireFox完全沒有做URLDecode這件事,也就是說如果我在Server端做URLEncode時,FireFox會全死.
  Chrome 針對UTF8 會做URLDecode動作 , 其它全不會做URLDecode動作, 也就是說如果檔名的編碼是ANSI時, Server不做URLEncode它會接受,但如果你做了URLEncode時它反而會亂,但它算是比較聰明的一種Browser.
  
  IE呢????結果IE是預設做URLDecode(檔名, UTF8)  , 就只接受這種,其它編碼你有編和沒編都一樣它完全不會做URLDecode動作. 它直接將URLEncode結果回傳給你

       後來我覺得自己來寫廠商的那支發動Http動作的程式,想看看接收後的http封包長相,結果收了Http header 內容,發現裏面並沒有告訴接收端它Filename是用什麼編碼進行URLEncode,那真的還蠻好奇為什麼IE / Chrome會知要針對UTF8做URLDecode動作???? 除非他們有辦法去拆FileName內容判斷是否存在中文字,Chrome比較聰明他有辦法去判斷中文字的編碼是否是ANSI,如果是他不進行URLDecode動作,所以我們可以取得正確的結果.如果有看到%那就用UTF8編碼去做URLDeCode動作.
IE我就不解了,理論上在沒有做URLEncode前應該很容易可以去判斷是否含中文字,它反而無法處理, 當你用UTF8做了URLEncode後,反而你會解....但其它UTF7,Unicode,ANSI...URLEncode出來的結果,你居然知道你無法解,你直接不做URLDecode???(可能它有做try ...catch吧! 如果當掉就以預設回傳???真的不解)

      測試結果發現Server端用什麼編碼做URLEncode那Client端就要用一樣的編碼進行URLDecode動作,不然會發生不可預期的問題,後來去看了一堆RFC的規範都沒看到統一的作法,最後我決定自己埋東西到Header中了,因為這是對未來最有彈性的作法

  我的作法如下:
 (1)Server端

   Header Name=Content-Disposition;
Header Value=attachment; filename=8b4f5421b70d46c390d776d064dc71fe2014%e5....%96%ac.pdf;CodePage=65001
決定在Header多加個參數,Client要多判斷此欄位值,再做不同處理
 
        另外 因為爬到另一篇文章http://www.motobit.com/help/scptutl/pa97.htm
     
        它描述的和我的測試結果是一樣的,所以我決定比照辦理,要增加判斷Client端Browser版本,如果你們和我一樣是用AP去發動可能也會取不到相關值,所以我的程式如下:

.NET C# AP程式上傳訊時時,是抓不到Request.ServerVariables["HTTP_USER_AGENT"]參數,
同時只有IE才會做URLDecode動作(因為我們查問題常常是直接URL貼到Browser再做處理),所以只有在某些情況才做URLEncode動作
string header = "attachment; filename={0};CodePage={1}";
            string sFileNameCodePage=string.Empty;
 
            //IE 要加入Ecoding 要判斷是否為IE或沒有才處理,因為經測試只有IE會用URLDecode其它瀏覽器都沒有支援,而且IE也只能用UTF8而已
            if (Request.ServerVariables["HTTP_USER_AGENT"] == null || (Request.ServerVariables["HTTP_USER_AGENT"] != null && Request.ServerVariables["HTTP_USER_AGENT"].ToUpper().IndexOf("MSIE") > -1))
            {
                sAttName = System.Web.HttpUtility.UrlEncode(sAttName, System.Text.Encoding.UTF8); //檔名進行Encode動作
                sFileNameCodePage = Encoding.UTF8.CodePage.ToString();
            }
=============================
後來將我的結論跟MS說,後來他很善良的跟我說這樣的判斷可以只有在IE6-IE10有效,後來他提供了IE11的判斷方式給我
if (Request.UserAgent == null || isIE())
{
    // 若是自行開發的.NET程式或是IE瀏覽器則進行編碼
    ... ...
}
else
{
    // 其他情況不進行編碼
    ... ...
}
 
private bool isIE()
{
    string strAgent = Request.UserAgent;
    System.Web.HttpBrowserCapabilities browser = Request.Browser;
 
    if (browser.Browser.ToString().ToLower() == "ie")    // IE 6~10
        return true;
    else if (strAgent.Contains("rv:") && strAgent.Contains("like Gecko") && strAgent.Contains("Trident"))    // IE 11
        return true;
    else
        return false;
}
===============
最後針對我懷疑.NET程式一定和IE有某種程度的關聯他也回覆我了, 如下所示:
您測試IE和應用程式的結果一致,這是因為他們在底層是用相同的windows API,所以結果才會是相同的,並非是.NET Framework用到IE的元件的問題。
 所以是windows API 兩台主機不同??????

技術果然是不歸路......:|

 


 


相簿設定
標籤設定
相簿狀態