2014-09-26 34 views
2

有關此問題的其他背景信息,請參閱Uploading/Downloading Byte Arrays with AngularJS and ASP.NET Web APIAngularJS使用ASP.NET Web API下載二進制數據時發生GET byte []錯誤

在上載/下載字節數組的TypeScript/AngularJS(v1.2.22)/ Web API解決方案中,我發現了一個場景,其中AngularJS沒有正確響應客戶端GET字節數組數據請求。爲了證明我的服務器代碼,我在Angular之外創建了一些單獨的XMLHttpRequest代碼,它可以與Web API服務器代碼正常工作。

  1. 可能有東西,我仍然在AngularJS代碼所缺少的,但我已經走遍了許多文件,文章和代碼示例,並沒有發現任何東西,顯然是錯誤的代碼。
  2. 我已經驗證通過Fiddler從服務器發送的數據對於AngularJS和XMLHttpRequest代碼是相同的。
  3. Angular代碼的第一個問題是它將數據解釋爲字符串,而不是字節數組,而XMLHttpRequest代碼將該代碼正確解釋爲字節數組。
  4. 第二個問題是AngularJS代碼破壞所有大於127的值(即128-255)。我包括了下面的這個屏幕截圖。
  5. 第三個問題是數據丟失。 AngularJS代碼中的重建數據只有217個字節,而不是256個字節。

這是可用的XMLHttpRequest代碼。請注意,該響應是UInt8Array構造函數的有效參數。

var oReq = new XMLHttpRequest(); 
    oReq.open("GET", "/api/Values", true); 
    // Worked on IE, Chrome, and Firefox with this line commented out, Firefox docs say it should be declared. 
    oReq.overrideMimeType("charset=x-user-defined"); 
    oReq.responseType = "arraybuffer"; 
    oReq.onload = function() { 
     var arrayBuffer = oReq.response, bArray = new Uint8Array(arrayBuffer), str = ""; 
     if (arrayBuffer) { 
      for (var i = 0; i < bArray.length; i++) { 
       str += bArray[i] + ((i < bArray.length - 1) ? "," : ""); 
      } 
      window.alert("XMLHttpRequest GET Output: " + str); 
     } 
    }; 

這裏是AngularJS代碼不能正常工作(即返回一個字節[]與正確的值)。請注意,響應必須從字符串轉換爲數組。

$http({ 
     method: 'GET', 
     url: 'api/values', 
     headers: {'Content-Type': 'application/octet-stream; charset=x-user-defined'}, 
     // The issue was caused by using camel case B. MUST BE 'arraybuffer' 
     // Changed code below to reflect correction. 
     responseType: 'arraybuffer', 
     transformResponse: [] 
    }).success(function (response, status) { 
      if (status === 200) {// Issue 1: response is not byte[]. It is a string. Issue 2: String values > 127 are corrupted. 
       var buffer = new ArrayBuffer(response.length), bArray = new Uint8Array(buffer), len = bArray.length, i, str = ""; 
       for (i = 0; i < len; i++) {// Cannot create an array from response data here, but I can using XMLHttpRequest. 
        str += bArray[i] = response[i].charCodeAt(0);// Have to read character value. 
        if (i < len - 1) 
         str += ","; 
       } 
       window.alert("Angular Output: " + str); 
       var unsigned8Int = new Uint8Array(bArray);// Can create new array here after processing string values. 
       var b64Encoded = btoa(String.fromCharCode.apply(null, unsigned8Int)); 
       callback(b64Encoded); 
      } 
     }).error((data, status) => { 
      console.log('[ERROR] Status Code:' + status); 
     }); 

我註釋了上述AngularJS代碼中的問題。我根據各種文章對上述代碼進行了許多修改,但都沒有成功。我嘗試了默認的transformResponse,但發現有一篇文章說默認值必須重置。

服務器端代碼如下:

[AcceptVerbs("Get")] 
    public HttpResponseMessage Get() 
    { 
     byte[] item = new byte[256]; 
     for (var i = 0; i < item.Length; i++) 
     { 
      item[i] = (byte)i; 
     } 
     HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); 
     result.Content = new ByteArrayContent(item); 
     result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); 
     return result; 
    } 

我檢查十六進制數據中的Fiddler下面每個測試用例,並且它是相同的(即,000102 ... EFFF),且長度在Fiddler中是256.在Angular代碼中,數據長度只有217和256,所以數據被破壞並丟失。

下面是兩個不同的GET代碼塊的屏幕截圖。

Screen Shots

我重複測試與服務器代碼,而不是256字節數組注入的圖像。同樣,在Fiddler中圖像數據內容(見下文)和長度(27,998字節)是相同的。

GET Image Response

的角碼塊內的接收到的圖像必須從一個字符串轉換爲一個字節數組,大小爲小得多(〜20K)。

似乎有兩種可能性:1)我的AngularJS代碼不好,或者2)Angular存在問題。

我將嘗試深入調試器中的AngularJS代碼,但我不知道我會得到多遠。

我真的可以用這個從你們中的一些人的幫助角運動員。

謝謝...

更新埃裏克Eslinger只是指出我的錯誤。 arrayBuffer必須arraybuffer BE(無駱駝)

回答

4

具體呼盡是

$http.get('http://example.com', {responseType: 'arraybuffer'}) 

,你會得到一個合適的二元響應。

相關問題