在 React JS 中使用 fetch 处理响应状态
Posted
技术标签:
【中文标题】在 React JS 中使用 fetch 处理响应状态【英文标题】:Handling response status using fetch in react JS 【发布时间】:2018-09-18 09:12:49 【问题描述】:我刚开始学习 ReactJS。现在我想知道当我使用 fetch 发出 API 请求时如何处理响应状态。这是我的代码:
componentDidMount()
this.setState( isLoading: true )
var id = this.props.match.params.id
const api = `bla/bla/$id`;
console.log("start call api")
fetch(api)
.then((response) =>
if(response.status === 200)
console.log("SUCCESSS")
return response.json();
else if(response.status === 408)
console.log("SOMETHING WENT WRONG")
this.setState( requestFailed: true )
)
.then((data) =>
this.setState( isLoading: false, downlines: data.response )
console.log("DATA STORED")
)
.catch((error) =>
this.setState( requestFailed: true )
)
console.log("end call api")
我关闭了连接以测试408
,但我的加载仍然出现。
render()
const isLoading, requestFailed = this.state;
if(requestFailed)
return(
<div className="errorContainer">
<a className="errorMessage">Opss.. Something went wrong :(</a>
</div>
)
这是我浏览器中的日志:
有什么办法可以解决这个问题吗?
【问题讨论】:
你能看到实际的状态编号吗?不一定是每个错误都是 408 检查response.ok
可能会更可靠。
@CertainPerformance 如果没有连接或请求超时等其他响应呢?
@kurniawan26 那么响应就不行了
tjvantoll.com/2015/09/13/fetch-and-errors
【参考方案1】:
当响应不正确时抛出错误,以便它直接进入catch
:
fetch(api)
.then((response) =>
if(!response.ok) throw new Error(response.status);
else return response.json();
)
.then((data) =>
this.setState( isLoading: false, downlines: data.response );
console.log("DATA STORED");
)
.catch((error) =>
console.log('error: ' + error);
this.setState( requestFailed: true );
);
【讨论】:
【参考方案2】:根据 MDN 文档:
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
当遇到网络错误或 CORS 在服务器端配置错误时, fetch() 承诺将拒绝并返回 TypeError,尽管这通常意味着权限问题或类似问题——例如,404 并不构成网络错误。对成功的 fetch() 的准确检查将包括检查 promise 是否已解决,然后检查 Response.ok 属性的值是否为 true。代码看起来像这样:
fetch('flowers.jpg').then(function(response)
if(response.ok)
return response.blob();
throw new Error('Network response was not ok.');
).then(function(myBlob)
var objectURL = URL.createObjectURL(myBlob);
myImage.src = objectURL;
).catch(function(error)
console.log('There has been a problem with your fetch operation: ',
error.message);
);
查看您的代码,我认为您的 408 错误检查永远不会运行。我认为事实上并没有。如果请求是 200ish ok,上面的代码基本上是返回 json 响应,否则它会抛出错误。如果发生错误,您的第二个则永远不会运行,它会被抛出到您的 catch 块。也许你可以在那里设置 isLoading: false ?
另外,您的 api 结束日志语句也不正确。这是在你的承诺完成之前调用的。
【讨论】:
谢谢...你的声明Perhaps you can set the isLoading: false there?
救救我..谢谢:D【参考方案3】:
如果你想在同一个返回值中同时知道json响应和错误码,我推荐这种方法:
async function loginUser(credentials)
var resp;
return fetch("http://127.0.0.1:8000/api/token-auth/",
method: "POST",
headers:
"Content-Type": "application/json"
,
body: JSON.stringify(credentials)
).then(response =>
resp = response;
return response.json();
).then(json =>
return
response: resp,
json: json,
error: !resp.ok
;
);
在这种情况下,您将获得一个包含response
、json
和error
字段的数组。如果您使用带有每个字段错误消息的 API,这是一种更好的方法:
"username":["This field is required."],"password":["This field is required."]
【讨论】:
【参考方案4】:如果您想同时捕获响应的状态代码和响应的正文,您可以使用此模式。对于我的项目,我创建了一个名为 Endpoint 的静态类来处理我的 API 调用。
export class Endpoint
static lastStatus = '';
static Get = (url, OKCallback, errorCallback = null) =>
fetch(url)
.then(response =>
Endpoint.lastStatus = response.status;
return response.json();
)
.then(getResponse =>
if (Endpoint.lastStatus == 200)
OKCallback(getResponse.body);
// else if (Endpoint.lastStatus == 408)
// Special logic or callback for status code 408 goes here.
else
console.log("API Error: " + JSON.stringify(getResponse));
if (errorCallback != null)
errorCallback(getResponse);
);
如果您有想要单独处理的特定 HTTP 状态代码,例如 408,您可以在第二个“then”块中添加自己的逻辑或回调来处理它们。
附:这种方法适用于我测试过的案例,但我不确定这是不是最好的方法。欢迎提供建设性反馈。
【讨论】:
以上是关于在 React JS 中使用 fetch 处理响应状态的主要内容,如果未能解决你的问题,请参考以下文章
React JS Fetch 返回空响应,但 Postman 没有
使用React Native Fetch中的对象响应时未处理的Promise Rejection