裸寫http body服務報body Unexpected end of multipart data的解決辦法


裸寫http body服務報body Unexpected end of multipart data的解決辦法

拋出異常:

  • 案例 調用騰訊OCR營業執照識別報錯。
調用騰訊OCR識別時簽名沒有問題,圖片base64也沒有問題,但是確收到對方服務報“內部錯誤”,經過聯系溝通,內部錯誤報:
“caught error Error: Unexpected end of multipart data”

抓包

通過抓包如下:

POST https://recognition.image.myqcloud.com/ocr/bizlicense HTTP/1.1
Content-Type: multipart/form-data; boundary=----------8d7055498b35e31
Authorization: yzo1HrKzdUF2rmYpiRoF482vvglhPTEyNTE3OTMwODAmYj10ZW5jZW50eXVuJms9QUtJRGExRDhtQmdBbEVWWWFSemp6emg5S0l6UWl2eTJDZUJUJmU9MTU2NTMzOTcxOSZ0PTE1NjI3NDc3MTkmcj0xOTA3MTAxNjM1JnU9MCZmPQ==
Host: recognition.image.myqcloud.com
Content-Length: 249
Expect: 100-continue


------------8d7055498b35e31
Content-Disposition: form-data; name="appid";

1251793080
------------8d7055498b35e31
Content-Disposition: form-data; name="image"; filename="yyzz.jpg"
Content-Type: image/jpeg


----------8d7055498b35e31--

解決問題

乍看上面抓包好像沒有什么問題,難道是Authorization加密出錯?圖片base64出錯?

其實真正出錯的的原因是Content-Type里面的橫線要比body里面的少兩個。body的最后一定要有兩個橫線結尾,並且body的橫線多少要一致(這個也是最重要的,不是有橫線就可以了)。

  • 能正確運行的包應該如下:
POST https://recognition.image.myqcloud.com/ocr/bizlicense HTTP/1.1
Content-Type: multipart/form-data; boundary=----------8d7055498b35e31
Authorization: yzo1HrKzdUF2rmYpiRoF482vvglhPTEyNTE3OTMwODAmYj10ZW5jZW50eXVuJms9QUtJRGExRDhtQmdBbEVWWWFSemp6emg5S0l6UWl2eTJDZUJUJmU9MTU2NTMzOTcxOSZ0PTE1NjI3NDc3MTkmcj0xOTA3MTAxNjM1JnU9MCZmPQ==
Host: recognition.image.myqcloud.com
Content-Length: 249
Expect: 100-continue


------------8d7055498b35e31
Content-Disposition: form-data; name="appid";

1251793080
------------8d7055498b35e31
Content-Disposition: form-data; name="image"; filename="yyzz.jpg"
Content-Type: image/jpeg


------------8d7055498b35e31--

附C#調用騰訊OCR營業執照識別的部分源碼

        static void IdentityBusinessLicense(string url)
        {
            HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(new Uri(url));
            Stream memStream = new MemoryStream();
            webReq.Method = "POST";
            string boundary = "----------" + DateTime.Now.Ticks.ToString("x");// 邊界符  
            webReq.ContentType = "multipart/form-data; boundary=" + boundary;
            //webReq.ContentType = "multipart/form-data;";
            byte[] enter = Encoding.ASCII.GetBytes("\r\n");  //換行
            memStream.Write(enter, 0, enter.Length);
            Dictionary<string, string> dic = new Dictionary<string, string>()
            {
                {"appid",OCRConfig.appid}
            };

            //寫入文本字段
            string inputPartHeaderFormat = "--" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"{0}\";" + "\r\n\r\n{1}\r\n";
            foreach (var kv in dic)
            {
                string inputPartHeader = string.Format(inputPartHeaderFormat, kv.Key, kv.Value);
                var inputPartHeaderBytes = Encoding.ASCII.GetBytes(inputPartHeader);
                memStream.Write(inputPartHeaderBytes, 0, inputPartHeaderBytes.Length);
            }
            var fileStream = new FileStream("yyzz.jpg", FileMode.Open, FileAccess.Read);
            // 寫入文件  
            string imagePartHeader = "--" + boundary + "\r\n" +
                                     "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n" +
                                     "Content-Type: image/jpeg\r\n\r\n";
            var header = string.Format(imagePartHeader, "image", "yyzz.jpg");
            var headerbytes = Encoding.UTF8.GetBytes(header);
            memStream.Write(headerbytes, 0, headerbytes.Length);
            var buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
            {
                memStream.Write(buffer, 0, bytesRead);
            }
            // 最后的結束符  
            byte[] endBoundary = Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
            memStream.Write(endBoundary, 0, endBoundary.Length);
            // webReq.ContentLength = memStream.Length;
            webReq.Headers.Add(HttpRequestHeader.Authorization, OCRApi.HmacSha1Sign());
            webReq.Host = OCRConfig.Host;
            var requestStream = webReq.GetRequestStream();
            memStream.Position = 0;
            memStream.CopyTo(requestStream);
            HttpWebResponse response = (HttpWebResponse)webReq.GetResponse();
            StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
            var ret = sr.ReadToEnd();
            sr.Close();
            response.Close();
            requestStream.Close();
            memStream.Close();
        }

總結

1、Content-Type: multipart/form-data; boundary=----------8d7055498b35e31 這里header的boundary橫線要比body的少兩個
2、------------8d7055498b35e31 body里面的橫線要比header的橫線要多兩個且所有body的橫線長度要一致,不是有橫線就可以了。
3、特別注意結尾處應該還有兩個“--”,注意是兩個橫線
4、還有一點就是要注意header之間,header與body之間,body與body之間的字段相隔多少個“\r\n”,這樣就可以了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM