2016-12-01 85 views
1

我有一個Angular 1.x應用程序,期望通過$http.post()調用來接收二進制文件下載(pdf)。問題是,我想要另外得到一個處理錯誤消息,這是作爲json發送的。我可以用配置Can Angular在接收到響應後設置responseType?

headers: { 
    'Accept': 'application/pdf, application/json' 
} 

問題是我必須要設置responseType: 'arraybuffer'做到這一點,否則PDF格式的二進制被轉義(或改變,使得它不會加載)。但是,這可以防止json被正確讀取或解釋。

我該怎麼做?

編輯:我會盡量澄清;也許我的理解是不正確的。

$http({ 
    method: 'POST', 
    url: "/myresource", 
    headers: { 
     'Accept': 'application/pdf, application/json' 
    }, 
    responseType: 'arraybuffer' 
}) 
.then(
    function(response) { 
     // handle pdf download via `new Blob([data])` 
    }, function(response) { 
     // pop up a message based on response.data 
    } 
) 

在我返回一個PDF數據塊和爲200的HTTP狀態的情形下,所述第一函數處理的響應,並且提示用戶保存文件。但是,如果狀態是錯誤(422),則response.data未定義。我認爲這是因爲responseType阻止正確處理json。

如果我刪除responseType行,錯誤數據可以正確讀取,但是當保存pdf時,某些文件字節不正確,並且實際上已損壞。我認爲這是因爲該文件正在編碼,因爲JavaScript期待一個字符串。

+0

不發送服務器錯誤作爲成功數據。將它們作爲錯誤發送。發送一個200錯誤消息來處理成功只會令API消費者感到困惑。 – Claies

+0

@Claies,我不會將錯誤發送爲200狀態(它是422)。 –

+0

@georgeawg,我正在爲每個響應設置相應的內容類型。 –

回答

5

XHR responseType屬性在加載響應後無法更改。但是,一個arraybuffer可以解碼並解析取決於Content-Type

var config = { 
    responseType: "arraybuffer", 
    transformResponse: jsonBufferToObject, 
    }; 

    function jsonBufferToObject (data, headersGetter, status) { 
     var type = headersGetter("Content-Type"); 
     if (!type.startsWith("application/json")) { 
     return data; 
     }; 
     var decoder = new TextDecoder("utf-8"); 
     var domString = decoder.decode(data); 
     var json = JSON.parse(domString); 
     return json; 
    }; 

    $http.get(url, config); 

上面的例子設置XHR返回一個arraybuffer和使用transformResponse功能檢測Content-Type: application/json並在必要時轉換。

DEMO on PLNKR

+0

是的,這是我正在尋找(不明白)。 –

+0

AngularJS $ http使用[XHR API](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest)。 [新的提取API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)可以同時執行或更改。 – georgeawg