RequestHeaderが間違って指定されたため、バックグラウンドでFormDataデータが受信できないという問題を解決

4413 ワード

問題の原因は、現在行われているWEB APIプロジェクトでformdataでバックグラウンドにデータ(JSONと画像1枚を含む)を提出する必要があることです.
以前は次のコードでデータを送信していましたが、問題はありませんでした.
                if (window.XMLHttpRequest) {     //   Mozilla                                          //  XMLHttpRequest  
                    xmlhttp = new XMLHttpRequest();
                } else if (window.ActiveXObject) {   //   IE         
                    try {
                        xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
                    } catch (e) {
                        try {
                            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
                        } catch (e) { }
                    }
                }

                var fd = new FormData();
                var file = document.getElementById('filebox_file_id_1');
                var fileList = file.files;
                if (fileList.length != 0)
                {

                    if (fileList[0].length / 1024 / 1024 > 20) {
                        alert("          (20MB),    !");
                        $('#fileToUpload').filebox('setValue', '');
                        return;
                    }
                    fd.append("fileToUpload", fileList[0]);
                }

                fd.append("data",JSON.stringify(jsondata));

                xmlhttp.open("POST", "../api/Company/Register", true);                                              //       ,         ,      
                xmlhttp.setRequestHeader("Content-Type", "multipart/form-data");            //POST       ,    
                xmlhttp.send(fd);                

しかし、その後、需要を変更するときにテストを行うと、火狐ブラウザで登録要求を提出するときにバックグラウンドでデータが取れないが、IEの下で正常であることが奇妙な問題を発見した(データを取るコードは以下の通り).
                JObject data = JObject.Parse(HttpContext.Current.Request["data"]);
                HttpFileCollection files = HttpContext.Current.Request.Files;
これはおかしいです.一般的に火狐の互換性はIEより良いからです.そこでFIDDLERバッグに.
まずTextViewを見てみると、フォーマットが完全に一致していて、バックグラウンドから取り出したInputStreamも同じです.
火狐
-----------------------------22544859410221
Content-Disposition: form-data; name="data"

{"f_CompanyName":"9","f_CompanyCode":"9","f_CompanyLicense":"9","f_Remark":""}
-----------------------------22544859410221--

IE
-----------------------------7e1346131e0382
Content-Disposition: form-data; name="data"

{"f_CompanyName":"9","f_CompanyCode":"9","f_CompanyLicense":"9","f_Remark":""}
-----------------------------7e1346131e0382--

しかしこのInputStreamが取り出した文字列には区切り文字情報が含まれており,直接JObjectに変換することはできず,正規表現では面倒なので解析を続ける.
リクエストヘッダを比較します.
火狐
POST http://localhost:2629/api/Company/Register HTTP/1.1
Host: localhost:2629
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data
Referer: http://localhost:2629/Web_Page/Register.aspx
Content-Length: 221
Cookie: CurrentUICulture=zh-CN
Connection: keep-alive

IE
POST http://localhost:2629/api/Company/Register HTTP/1.1
Accept: */*
Content-Type: multipart/form-data, multipart/form-data; boundary=---------------------------7e1346131e0382
Referer: http://localhost:2629/Web_Page/Register.aspx#
Accept-Language: zh-CN
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Host: localhost:2629
Content-Length: 219
Connection: Keep-Alive
Pragma: no-cache

比較してみると、火狐のTypeにはboundaryが欠けていて、このboundaryは区切り記号で、表の単項を分割するために使われていることがわかります.区切り記号が指定されていないバックグラウンドではCurrentを通過できません.Requestはフォームアイテムを取得しました.
理由を知ってからコードを振り返って、こんな言葉を見つけました.
                xmlhttp.setRequestHeader("Content-Type", "multipart/form-data");            //POST       ,    

明らかに問題だ.
解析ブラウザで生成されたプロトコルヘッダを解析すると,IEはコードで指定されたコンテンツタイプを受け入れたが,また自分のタイプを追加した(解析に影響しないようだが),火狐は直接コードで指定されたタイプを用いたため,区切り文字情報が欠けている.
今回の問題は私に注意して、ネット上でも前のプロジェクトの中ですり取ったコードも直接使わないでください、少なくとも理解できるようにして、すべての文がどういう意味かを知っていて、さもなくば各種の奇抜な問題が現れるのは避けられません.