1

我试图弄清楚如何在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属性未定义。

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

4

1 回答 1

3

问题是CORS。您正在使用的服务器将包含Access-Control-Allow-Origin: *带有响应的标头2xx,但不包含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-corsmode 来解决此问题。和bs-fetch你一起做:

Fetch.fetchWithInit(url, Fetch.RequestInit.make(~mode=Fetch.NoCORS, ()))
于 2018-02-19T14:40:18.863 回答