我有一个fetch-api POST请求:
fetch(url, {
method: 'POST',
body: formData,
credentials: 'include'
})
我想知道这个的默认超时时间是多少?我们如何将它设置为特定的值,比如3秒或不定秒?
我有一个fetch-api POST请求:
fetch(url, {
method: 'POST',
body: formData,
credentials: 'include'
})
我想知道这个的默认超时时间是多少?我们如何将它设置为特定的值,比如3秒或不定秒?
当前回答
基于无尽的回答,我创造了一个有用的效用函数。
const fetchTimeout = (url, ms, { signal, ...options } = {}) => {
const controller = new AbortController();
const promise = fetch(url, { signal: controller.signal, ...options });
if (signal) signal.addEventListener("abort", () => controller.abort());
const timeout = setTimeout(() => controller.abort(), ms);
return promise.finally(() => clearTimeout(timeout));
};
如果在获取资源之前达到了超时,则会中止获取。 如果在超时之前获取资源,则超时将被清除。 如果输入信号被中止,那么取回将被中止,超时时间将被清除。
const controller = new AbortController();
document.querySelector("button.cancel").addEventListener("click", () => controller.abort());
fetchTimeout("example.json", 5000, { signal: controller.signal })
.then(response => response.json())
.then(console.log)
.catch(error => {
if (error.name === "AbortError") {
// fetch aborted either due to timeout or due to user clicking the cancel button
} else {
// network error or json parsing error
}
});
其他回答
更新,因为我最初的答案有点过时,我建议使用像这里实现的中止控制器:https://stackoverflow.com/a/57888548/1059828或看看这个非常好的帖子解释中止控制器与fetch:我如何取消HTTP fetch()请求?
过时的原答案:
我非常喜欢使用Promise.race这种简洁的方法
fetchWithTimeout.js
export default function (url, options, timeout = 7000) {
return Promise.race([
fetch(url, options),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('timeout')), timeout)
)
]);
}
main.js
import fetch from './fetchWithTimeout'
// call as usual or with timeout as 3rd argument
// throw after max 5 seconds timeout error
fetch('http://google.com', options, 5000)
.then((result) => {
// handle result
})
.catch((e) => {
// handle errors and timeout error
})
如果您没有在代码中配置超时,它将是浏览器的默认请求超时。
1) Firefox - 90秒
在Firefox URL字段中输入about:config。找到key network.http.connection-timeout对应的值
2) Chrome - 300秒
源
下面是一个使用NodeJS的SSCCE,它将在1000ms后超时:
import fetch from 'node-fetch';
const controller = new AbortController();
const timeout = setTimeout(() => {
controller.abort();
}, 1000); // will time out after 1000ms
fetch('https://www.yourexample.com', {
signal: controller.signal,
method: 'POST',
body: formData,
credentials: 'include'
}
)
.then(response => response.json())
.then(json => console.log(json))
.catch(err => {
if(err.name === 'AbortError') {
console.log('Timed out');
}}
)
.finally( () => {
clearTimeout(timeout);
});
基于无尽的回答,我创造了一个有用的效用函数。
const fetchTimeout = (url, ms, { signal, ...options } = {}) => {
const controller = new AbortController();
const promise = fetch(url, { signal: controller.signal, ...options });
if (signal) signal.addEventListener("abort", () => controller.abort());
const timeout = setTimeout(() => controller.abort(), ms);
return promise.finally(() => clearTimeout(timeout));
};
如果在获取资源之前达到了超时,则会中止获取。 如果在超时之前获取资源,则超时将被清除。 如果输入信号被中止,那么取回将被中止,超时时间将被清除。
const controller = new AbortController();
document.querySelector("button.cancel").addEventListener("click", () => controller.abort());
fetchTimeout("example.json", 5000, { signal: controller.signal })
.then(response => response.json())
.then(console.log)
.catch(error => {
if (error.name === "AbortError") {
// fetch aborted either due to timeout or due to user clicking the cancel button
} else {
// network error or json parsing error
}
});
使用c-promise2库,可取消的获取超时可能像这样(Live jsfiddle演示):
import CPromise from "c-promise2"; // npm package
function fetchWithTimeout(url, {timeout, ...fetchOptions}= {}) {
return new CPromise((resolve, reject, {signal}) => {
fetch(url, {...fetchOptions, signal}).then(resolve, reject)
}, timeout)
}
const chain = fetchWithTimeout("https://run.mocky.io/v3/753aa609-65ae-4109-8f83-9cfe365290f0?mocky-delay=10s", {timeout: 5000})
.then(request=> console.log('done'));
// chain.cancel(); - to abort the request before the timeout
这段代码作为一个npm包cp-fetch