【问题标题】:Resolved fetch throws console error 401已解决的 fetch 引发控制台错误 401
【发布时间】:2018-06-22 09:28:00
【问题描述】:

我的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 使用任何填充物包装。 Chrome 版本为 63.0.3239.108。

【问题讨论】:

  • 错误来自服务器。预期行为会在控制台中显示错误。
  • Chrome 在控制台中显示失败的请求。我相信非 200 或 300 会被认为是失败的。看起来fetch 确实 not 拒绝失败的请求。检查状态码由您决定。以下是fetch 拒绝的一些原因:github.com/github/fetch/issues/201#issuecomment-308213104

标签: javascript promise fetch-api


【解决方案1】:

Fetch 正在按预期工作。你从服务器得到了一个有效的响应,只是这个端点需要某种授权,并返回一个状态码为401的响应。

从 fetch() 返回的 Promise 不会拒绝 HTTP 错误状态 即使响应是 HTTP 404 或 500。相反,它会解析 通常(ok状态设置为false),它只会拒绝 网络故障或是否有任何事情阻止请求完成。

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401

【讨论】:

    【解决方案2】:

    这实际上与 fetch 本身没有什么共同之处。默认情况下的 Chrome 开发工具在控制台中记录 HTTP 错误(4xx 和 5xx 状态),如 Additional settings section here 中所述。所以你的 fetch 承诺可以成功解决,你只能看到可以关闭的浏览器日志。

    【讨论】:

      【解决方案3】:

      请在您的代码服务器中设置您的标头。

       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');
      

      【讨论】:

        【解决方案4】:

        发生这种情况是因为响应中缺少 CORS 标头。我通过添加以下内容使其按预期工作:

        @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"));
                }
        
        
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2021-07-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-12-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多