fetch 即使 404 也能解决?
Posted
技术标签:
【中文标题】fetch 即使 404 也能解决?【英文标题】:fetch resolves even if 404? 【发布时间】:2017-01-10 20:41:07 【问题描述】:使用此代码:
fetch('notExists') // <---- notice
.then(
function(response)
alert(response.status)
)
.catch(function(err)
alert('Fetch Error : ', err);
);
这个承诺解决。
mdn
它返回一个可以解析为该请求的响应的承诺, 不管成功与否。
一个失败的 ajax 请求即使转到一个不存在的资源也得到了解决,这不是很奇怪吗?
我的意思是——接下来呢?将fetch
发送到已关闭但仍获得已解决承诺的服务器?
我知道我可以在 response
对象的 ok
属性上进行调查,但仍然 -
问题
为什么会为完全错误的请求(非现有资源)解决提取问题。
BTW , jquery request , does get rejected
【问题讨论】:
它必须解决才能处理错误代码。 @Barmar 那么为什么不在 catch/reject 处理程序上呢? 您希望获取标准的作者回复吗?因为他们将是那些无需猜测就能回答这个问题的人。 @MikeMcCaughan 我只是想找到答案。我不希望 Henrik 在这里回答 :-) 我同意,404 不走错误路径是疯狂的。 【参考方案1】:拒绝处理程序用于网络和 CORS 错误 iirc。如果请求到达服务器并以有效的 http 响应进行响应,则即使响应代码为 4xx 或 5xx,promise 也会得到满足。
【讨论】:
【参考方案2】:fetch()
调用仅在网络请求本身因某种原因失败(未找到主机、未连接、服务器未响应等...)时才会被拒绝。
从承诺的角度来看,从服务器返回的任何结果(404、500 等...)都被视为成功请求。从概念上讲,您从服务器发出请求,服务器响应您,因此从网络的角度来看,请求成功完成。
然后您需要测试该成功响应以查看是否有您想要的答案类型。如果您希望 404 被拒绝,您可以自己编写代码:
fetch('notExists').then(function(response)
if (!response.ok)
// make the promise be rejected if we didn't get a 2xx response
const err = new Error("Not 2xx response");
err.response = response;
throw err;
else
// go the desired response
).catch(function(err)
// some error here
);
您甚至可以创建自己的 myFetch()
,它会自动为您执行此操作(将任何非 200 响应状态转换为拒绝)。
已解决的承诺背后的原因是什么? 请求(非现有资源/服务器停机)。
首先,服务器关闭不会产生成功的响应 - 会拒绝。
如果您成功连接到服务器,向其发送请求并返回响应(任何响应),则会生成成功响应。至于“为什么”fetch()
界面的设计者决定以此为由拒绝,如果不与实际参与该界面设计的人交谈,就很难说,但对我来说这似乎是合乎逻辑的。通过这种方式,拒绝会告诉您请求是否通过并得到有效响应。由您的代码决定如何处理响应。当然,您可以创建自己的包装函数来修改默认行为。
【讨论】:
哦,好吧,我知道没有地方可以比较,但$.ajax
到 //a
确实被拒绝了。 jsbin.com/pukurolego/1/edit?html,js,output
@RoyiNamir - 我不认为你是 jsbin 的例子正在做你认为的事情。如果我console.log()
拒绝错误,我会看到这个Failed to load resource: net::ERR_ADDRESS_UNREACHABLE http://0.0.0.22/
。我不确切知道 jQuery 的行为方式,但你的 jsbin 没有测试正确的东西。
你说得对,我的错,没看到。我需要休息。【参考方案3】:
使用此代码...
fetch(`https://fercarvo.github.io/apps/integradora/DB/corpus.json`)
.then(async (data) =>
if (data.ok)
data = await data.json()
//Here you have your data...
).catch(e => console.log('Connection error', e))
【讨论】:
【参考方案4】:以@fernando-caravajal 示例为基础(这对我来说更容易用于异步/等待),我在下面制作了这个稍作修改的版本,用于发布查询,并发送了参数。我添加了throw new Error
语句,因为我无法捕捉到response.ok == false
上的故障。
/**
* Generic fetch function
*/
function fetchData(url,parameters,callback)
fetch(url,
method: "POST",
headers: "Content-Type": "application/json" ,
body: JSON.stringify(parameters),
)
.then(async(response) =>
// status 404 or 500 will set ok to false
if (response.ok)
// Success: convert data received & run callback
result = await response.json();
callback(result);
else
throw new Error(response.status + " Failed Fetch ");
).catch(e => console.error('EXCEPTION: ', e))
【讨论】:
【参考方案5】:正如其他人所说, fetch 仅在出现适当的网络问题时才返回错误。 “down”服务器不会返回 4XX,它不会返回任何内容或 5XX,具体取决于它是如何“down”的。 我倾向于使用 axios 而不是 fetch 主要是因为这个问题让我编写了更多代码。
【讨论】:
以上是关于fetch 即使 404 也能解决?的主要内容,如果未能解决你的问题,请参考以下文章
我Nginx服务器设置了404,也能跳转到404但是返回状态码是200?