이 문제점에 대한 추가 배경 정보는 Uploading/Downloading Byte Arrays with AngularJS and ASP.NET Web API을 참조하십시오.ASP.NET Web API를 사용하여 이진 데이터를 다운로드 할 때 AngularJS GET byte [] 오류
Upload/Download 바이트 배열을위한 TypeScript/AngularJS (v1.2.22)/Web API 솔루션을 작업하면서 AngularJS가 바이트 배열 데이터에 대한 클라이언트 측 GET 요청에 올바르게 응답하지 않는 시나리오를 발견했습니다. 내 서버 코드를 증명하기 위해 Web API 서버 코드에서 제대로 작동하는 Angular 외부에 별도의 XMLHttpRequest 코드를 만들었습니다.
- AngularJS 코드에는 아직 누락 된 것이있을 수 있지만 많은 문서, 기사 및 코드 예제를 훑어보고 코드에 오류가있는 것은 발견하지 못했습니다.
- 필자는 AngularJS 및 XMLHttpRequest 코드에서 Fiddler를 통해 서버에서 보낸 데이터가 동일하다는 것을 확인했습니다.
- Angular 코드의 첫 번째 문제는 XMLHttpRequest 코드가 해당 코드를 올바르게 바이트 배열로 해석하는 동안 바이트 배열이 아닌 문자열로 데이터를 해석한다는 것입니다.
- 두 번째 문제는 AngularJS 코드가 127보다 큰 모든 값 (예 : 128-255)을 손상시키는 것입니다. 나는 이것의 스크린 샷을 아래에 포함시켰다.
- 세 번째 문제는 데이터가 손실된다는 것입니다. AngularJS 코드의 재구성 된 데이터는 256 바이트 대신 217 바이트 만있었습니다.
다음은 작동하는 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 시도했지만 기본값을 다시 설정해야했다 한 기사를 발견했습니다.
서버 측 코드는 다음과 같다 : I는 아래 각 테스트 케이스에 대한 피들러의 헥스 데이터를 체크하고 (즉, 000,102 ... EFFF) 동일이고, 길이
[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의 경우 256이었습니다. Angular 코드에서 데이터 길이는 256에 비해 217 이었으므로 데이터가 손상되어 손실되었습니다.
다음은 위의 두 가지 다른 GET 코드 블록의 두 가지 스크린 샷입니다.
난 서버 코드 대신에 256 바이트의 배열에 주입 된 이미지와 시험을 반복했다. 다시, 이미지 데이터 내용 (아래 참조)과 길이 (27,998 바이트)는 Fiddler에서 동일했습니다.각 코드 블록 내의 수신 된 이미지는 바이트 배열 문자열에서 변환 할 수 있었고, 크기 (~ 20K) 훨씬 작았 다.
두 가지 가능성이있는 것 같습니다. 1) 내 AngularJS 코드가 좋지 않거나 2) 각도에 문제가 있습니다.
디버거에서 AngularJS 코드로 다이빙을 시도하지만 얼마나 멀리 얻을 수 있는지 잘 모르겠습니다.
저는 여러분 중 몇 분께 도움을받을 수 있습니다. 업데이트 에릭 Eslinger 그냥 내 오류를 지적
감사합니다 .... arrayBuffer 만들 수