已解决 fetch 抛出控制台错误 401
Resolved fetch throws console error 401
我的 fetch
日志控制台错误,尽管已通过 401 Unauthorized
解决
componentWillMount() {
this.setState({ isInitializing: true });
fetch('/api/users/getcurrent')
.then(resp => {
console.log('resolved');
if (resp.status == 200) {
// do stuff
}
this.setState({ isInitializing: false });
})
.catch(err => {
console.log('catched');
this.setState({ isInitializing: false });
});
}
这是 fetch 的预期行为吗?我没有看到任何与 MDN 或其他任何地方的 401 抛出错误相关的内容。控制台记录是合法错误。我没有为 fetch
使用任何 polyfill 包。 Chrome 版本为 63.0.3239.108。
Fetch 正在按预期工作。你从服务器得到了一个有效的响应,只是这个端点需要某种授权并发回了一个状态代码为 401
.
的响应
The Promise returned from fetch() won’t reject on HTTP error status
even if the response is an HTTP 404 or 500. Instead, it will resolve
normally (with ok status set to false), and it will only reject on
network failure or if anything prevented the request from completing.
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401
这其实和fetch本身没什么共同点。 Chrome 默认情况下的开发工具会在控制台中记录 HTTP 错误(4xx 和 5xx 状态),如 Additional settings section here 中所述。所以你的 fetch promise 可以成功解决,你只看到可以关闭的浏览器日志。
请在您的代码服务器中设置您的header。
res.header('Access-Control-Allow-Origin','*');
res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method');
res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE');
res.header('Allow', 'GET, POST, OPTIONS, PUT, DELETE');
发生这种情况是因为响应中缺少 CORS headers。我通过添加以下内容使其按预期工作:
@Component
public class CORSHeadersToUnauthorizedResponseFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
FilterChain filterChain) throws IOException, ServletException {
filterChain.doFilter(httpServletRequest, httpServletResponse);
if(httpServletResponse.getStatus() == HttpStatus.UNAUTHORIZED.value() ) {
httpServletResponse.addHeader("Access-Control-Allow-Credentials", "true");
httpServletResponse.setHeader("Access-Control-Allow-Origin", httpServletRequest.getHeader("origin"));
}
}
}
我的 fetch
日志控制台错误,尽管已通过 401 Unauthorized
componentWillMount() {
this.setState({ isInitializing: true });
fetch('/api/users/getcurrent')
.then(resp => {
console.log('resolved');
if (resp.status == 200) {
// do stuff
}
this.setState({ isInitializing: false });
})
.catch(err => {
console.log('catched');
this.setState({ isInitializing: false });
});
}
这是 fetch 的预期行为吗?我没有看到任何与 MDN 或其他任何地方的 401 抛出错误相关的内容。控制台记录是合法错误。我没有为 fetch
使用任何 polyfill 包。 Chrome 版本为 63.0.3239.108。
Fetch 正在按预期工作。你从服务器得到了一个有效的响应,只是这个端点需要某种授权并发回了一个状态代码为 401
.
The Promise returned from fetch() won’t reject on HTTP error status even if the response is an HTTP 404 or 500. Instead, it will resolve normally (with ok status set to false), and it will only reject on network failure or if anything prevented the request from completing.
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401
这其实和fetch本身没什么共同点。 Chrome 默认情况下的开发工具会在控制台中记录 HTTP 错误(4xx 和 5xx 状态),如 Additional settings section here 中所述。所以你的 fetch promise 可以成功解决,你只看到可以关闭的浏览器日志。
请在您的代码服务器中设置您的header。
res.header('Access-Control-Allow-Origin','*');
res.header('Access-Control-Allow-Headers', 'Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method');
res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE');
res.header('Allow', 'GET, POST, OPTIONS, PUT, DELETE');
发生这种情况是因为响应中缺少 CORS headers。我通过添加以下内容使其按预期工作:
@Component
public class CORSHeadersToUnauthorizedResponseFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
FilterChain filterChain) throws IOException, ServletException {
filterChain.doFilter(httpServletRequest, httpServletResponse);
if(httpServletResponse.getStatus() == HttpStatus.UNAUTHORIZED.value() ) {
httpServletResponse.addHeader("Access-Control-Allow-Credentials", "true");
httpServletResponse.setHeader("Access-Control-Allow-Origin", httpServletRequest.getHeader("origin"));
}
}
}