js fetch函數如何寫才能解決Unexpected end of JSON input?

我現在用的是reactjs做前台,我的post函數如下:

export function post (url, body, callback) {
fetch(configUrl + url, {
method: "POST",
headers: {
"Accept": "application/json",
"Content-Type": "application/json;charset=utf-8"
},
credentials: "include", //這個參數不加,後台取不到Cookie
body : JSON.stringify(body),
mode : "cors" //實現跨域 默認是 same-origin , no-core ,core
// headers: form.getHeaders()
}).then(function(res){
logUtils.logFetchResponse(res);
let results = res.json();
return results;
}).then(function(data){
logUtils.logFetchDate(data);
callback(data);
});
}

我的問題是,這裡最後一個then如果data沒有返回值的話就會報錯:

undefined:1 Uncaught (in promise) SyntaxError: Unexpected end of JSON input

這個錯誤原因就是如果data為空就不能調用第二個then。

但是,我們有後台rest介面有自定義異常錯誤,這次異常的errorCode和errorMessage只能在data裡面取到(response只能獲得200、500),也就是說post請求沒有返回值,但是我需要取後台自定義的錯誤信息給前端展示,所以第二個then我是肯定要的,但是如果post請求成功,data就沒值了,就會報錯,這個錯誤會導致我的reactjs整個都不能繼續下去了。請懂的大神指導下:

1、如果前後端都懂,是否我們rest介面寫的不好?(自定義的異常為啥只能從data取到,是否後台介面上做修改可以直接從response取到)

2、是否我的fetch介面寫的有問題,如果這裡可以處理,求驗證寫出來!

3、我的這個錯誤信息判斷為在第二個then的地方是否正確?(我自己也不是非常確定,但是調試就在這報錯了)

先謝謝了,大家隨意指導,只要能給我解決這個問題的思路,具體的我可以自己實踐,只要是我現在實在找不到方向了。

========補充的分割線==========================

如果使用這種方式,如果調用介面錯誤,data就是一個promise對象,不是我需要的包裝好的有errorCode和errorMessage的對象了,如下圖:

而成功了話還是會報Uncaught (in promise) SyntaxError: Unexpected end of JSON input這個錯誤

另外,如果我使用else return Promise.resolve(results);

data居然變成SyntaxError對象了,也是醉醉的,如下圖:


UPDATE:

fetch(...)
.then(res =&> {
if(!res.ok) res.json().then(err =&> throw err)
})
.catch(err =&> {
//handle error
})

-----------------------------------------------------------------------------------------------------------------------------------------

不確定是不是理解你的問題了,但是我一般寫REST的時候,都會給創建一個Result的基類,大概是這樣的:

Return ::= {
code: Int,
message: String,
data: Any
}

這樣的話我,無論請求成功還是失敗,我在處理的時候都可以走一個一般處理流程,這樣對前端是friendly的。

至於你的問題我覺得也不是不好處理,你試試看這樣?

fetch(...)
.then(res =&> {
logUtils.logFetchResponse(res)
if(!res.ok) return Promise.reject(res.json())
//正常情況下,then chain在這裡就結束了,但如果res不為20x,則進入catch分支的異常處理流程
})
.catch(err =&> {
//handle your server defined error?
})


推薦閱讀:

比較redux和reflux以及自己寫個TinyFlux?
為什麼瀏覽器不將類似react.js的虛擬DOM在其內部實現呢?
如何理解虛擬DOM?
如何用React做一個MVC項目?
在 componentWillUnmount 中到底應該清除哪些變數?

TAG:前端開發 | JavaScript | REST | HTTP | React |