在服務器返回ResponseEntity<byte[]>這種二進制流的情況下,對於異常的捕獲封裝返回的卻仍然是json,今天折騰了很久
總結如下:
該接口返回值爲ResponseEntity<byte[]>,有異常攔截@ExceptionHandler@ResponseStatus,當在下載文件時出現了異常,則不會返回二進制流,而返回異常攔截定義的返回值,在此假設爲{code:200,messege:"e"},HttpStatus=500。
前端使用fetch請求的代碼如下:
fetch(url,{options})
//以前沒有先行判斷res.status,後來發現不判斷會很麻煩,因爲按照後端習慣來說,全部返回200,然後封裝結果集也是可以完成任務的;後來像今天這種情景讓我知道了果然不按照標準走,解決方案會tm多敲很多字吶。
.then(function(res){
if(res.status==200){return res;}
const error=new Error(res.statusText);
error.response=res;
})
.then(function(res){
//下載文件這一套,文件名按照習慣來說是封裝在Content-Disposition中的
let filename=decodeURI(res.headers.get("Content-Disposition").split("; ")[1].split("=")[1])
//正常流程res中是blob二進制流
return res.blob().then(function(blob){/**這中間是保存二進制流的方法,網上很多就不敲了*/})
})
.catch(function(err){
//這裏我們說過,當http status不爲200時,返回的是json
res.json().then(function(data){/**這裏的data就是json了。按照json的方式處理即可*/})
})
基本上就是這樣,今天這波問題出的我是猝不及防,本來想着在別的ajax上處理異常直接判斷就可以,萬萬沒想到下載這裏出了這種事情,今天卡的主要位置就是res轉json,怎麼轉都拿不到,去查了Promise模型才知道,fetch的request和response提供了arrayBuffer(),blob(),json(),text(),formData(),這些方法都實現了Promise模型(類似java的FunctionInterface),都需要進行callback才能操作數據。就像這樣:res.json().then(function(data){})