【问题标题】:Fetch rejects promise on 404 responses instead of resolving with 404 statusFetch 拒绝对 404 响应的承诺,而不是用 404 状态解析
【发布时间】:2018-02-19 22:41:57
【问题描述】:

我试图弄清楚如何在reason-react-example repo 的 fetch 示例中处理失败的 http 响应。

以下是我的第一个想法(修改网址):

Js.Promise.(
          Fetch.fetch("https://dog.ceo/api/breeds/list")
          |> then_(res => {
               let ok = Fetch.Response.ok(res);
               ok ?
                 Fetch.Response.json(res) :
                 Js.Exn.raiseError(Fetch.Response.statusText(res));
             })
          |> then_(json =>
               json
               |> Decode.dogs
               |> (dogs => self.send(DogsFetched(dogs)))
               |> resolve
             )
          |> catch(err => {
               Js.log(err);
               [%bs.raw {| console.log(err.response) |}]
               Js.Promise.resolve(self.send(DogsFailedToFetch));
             })
          |> ignore
        );

它没有像我希望的那样工作。事实证明,当 HTTP 请求以 404 失败时,Fetch 立即拒绝,这是我没想到的,因为浏览器获取 API 不是这样工作的。此外,当 err 被记录时,它是 TypeError: Failed to fetch 并且 err.response 属性未定义。

我的问题是:例如如何处理错误以获取状态代码和状态文本?

【问题讨论】:

    标签: cors fetch-api reason bucklescript reason-react


    【解决方案1】:

    问题是 CORS。您正在使用的服务器将包含一个带有 2xx 响应的 Access-Control-Allow-Origin: * 标头,但不包含 404 响应。所以显然你只能从这个服务器读取成功的响应。

    您应该在控制台中收到一些额外的警告或错误,告诉您以下内容:

    跨域请求被阻止:同源策略不允许读取位于https://dog.ceo/api/breeds/listio 的远程资源。 (原因:CORS 标头“Access-Control-Allow-Origin”缺失)。

    [错误] Access-Control-Allow-Origin 不允许 Origin null。

    [错误] 加载资源失败:Access-Control-Allow-Origin 不允许 Origin null。 (列表,第 0 行)

    [错误] Fetch API 无法加载 https://dog.ceo/api/breeds/listio。 Access-Control-Allow-Origin 不允许 Origin null。

    至少在测试时,您可以改用no-cors 模式来解决此问题。使用bs-fetch 你会这样做:

    Fetch.fetchWithInit(url, Fetch.RequestInit.make(~mode=Fetch.NoCORS, ()))
    

    【讨论】:

    • 注意glennsl的至少在测试时位!否则,当您转移到生产环境时,这将再次对您不利。仅供参考:)
    猜你喜欢
    • 2020-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-11
    • 2017-01-20
    • 1970-01-01
    • 2015-06-10
    相关资源
    最近更新 更多