获取拒绝承诺404响应而不是解析404状态

时间:2018-02-19 11:30:37

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

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

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

1 个答案:

答案 0 :(得分:1)

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

您应该在控制台中收到一些警告或错误,告诉您类似的内容:

  

阻止跨源请求:同源策略禁止在https://dog.ceo/api/breeds/listio读取远程资源。 (原因:缺少CORS标题'Access-Control-Allow-Origin'。

  

[错误] Access-Control-Allow-Origin不允许原点为空。

     

[错误]无法加载资源:Access-Control-Allow-Origin不允许使用Origin null。 (listio,第0行)

     

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

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

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