Fetch 拒绝对 404 响应的承诺,而不是使用 404 状态解析
Fetch rejects promise on 404 responses instead of resolving with 404 status
我正在尝试弄清楚如何在 reason-react-example 存储库的获取示例中处理失败的 http 响应。
以下是我的第一个想法(修补url):
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。您使用的服务器将包含 Access-Control-Allow-Origin: *
header 和 2xx
响应,但不包含 404
响应。所以显然你只能从这个服务器读取成功的响应。
您应该会在控制台中收到一些额外的警告或错误,告诉您类似以下内容:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://dog.ceo/api/breeds/listio. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
或
[Error] Origin null is not allowed by Access-Control-Allow-Origin.
[Error] Failed to load resource: Origin null is not allowed by Access-Control-Allow-Origin. (listio, line 0)
[Error] Fetch API cannot load https://dog.ceo/api/breeds/listio. Origin null is not allowed by Access-Control-Allow-Origin.
您可以通过使用 no-cors
模式来解决这个问题,至少在测试时是这样。使用 bs-fetch
你会做:
Fetch.fetchWithInit(url, Fetch.RequestInit.make(~mode=Fetch.NoCORS, ()))
我正在尝试弄清楚如何在 reason-react-example 存储库的获取示例中处理失败的 http 响应。
以下是我的第一个想法(修补url):
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。您使用的服务器将包含 Access-Control-Allow-Origin: *
header 和 2xx
响应,但不包含 404
响应。所以显然你只能从这个服务器读取成功的响应。
您应该会在控制台中收到一些额外的警告或错误,告诉您类似以下内容:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://dog.ceo/api/breeds/listio. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
或
[Error] Origin null is not allowed by Access-Control-Allow-Origin.
[Error] Failed to load resource: Origin null is not allowed by Access-Control-Allow-Origin. (listio, line 0)
[Error] Fetch API cannot load https://dog.ceo/api/breeds/listio. Origin null is not allowed by Access-Control-Allow-Origin.
您可以通过使用 no-cors
模式来解决这个问题,至少在测试时是这样。使用 bs-fetch
你会做:
Fetch.fetchWithInit(url, Fetch.RequestInit.make(~mode=Fetch.NoCORS, ()))