axios 库中的超时功能不起作用
Timeout feature in the axios library is not working
我设置了axios.defaults.timeout = 1000;
我停止了向我提供 API 的服务器。
但是发送请求后超时1s多
我的请求是这样的:
import axios from 'axios';
axios.defaults.timeout = 1000;
return axios.post(`${ROOT_URL}/login/${role}`, creds).then((response) => {
console.log(response);
if(response.status === 200) {
// If login was successful, set the token in local storage
localStorage.setItem(`${role}_log_toks`, JSON.stringify(response.data));
// Dispatch the success action
dispatch(receiveLogin(response.data));
return response;
}
}).catch(err => {
console.log(err);
// If there was a problem, we want to
// dispatch the error condition
if(err.data && err.status === 404) {
dispatch(loginError(err.data));
} else {
dispatch(loginError('Please check your network connection and try again.'));
}
return err;
});
我也试过:
return axios.post(`${ROOT_URL}/login/${role}`, creds, {timeout: 1000}).then...
Axios 没有停止抓取,5-10 分钟后它终于显示网络错误。我知道还有其他技术可以处理超时,但为什么 axios 中的超时功能不起作用? axios 不停止获取的原因可能是什么?
编辑:
如评论中所述,我也尝试过:
import axios from 'axios';
const httpClient = axios.create();
httpClient.defaults.timeout = 500;
return httpClient.post(`${ROOT_URL}/login/${role}`, creds)
.then(handleResponse)
您需要创建一个 axios http 客户端的实例:
const httpClient = axios.create();
httpClient.defaults.timeout = 500;
然后您可以按如下方式使用 httpClient:
return httpClient.post(`${ROOT_URL}/login/${role}`, creds)
.then(handleResponse)
附带说明一下,您还可以在同一配置中设置基础 url 而不是使用 ${ROOT_URL}
:
httpClient.defaults.baseURL = ROOT_URL
这段代码对我有用:
axios({
method: "post",
url: 'http://example.com/api',
timeout: 1000 * 5, // Wait for 5 seconds
headers: {
"Content-Type": "application/json"
},
data: {
id: 1234
}
})
.then(response => {
const serverResponse = response.data;
// do sth ...
})
.catch(error => {
console.log(error);
});
如果服务器在 5 秒内没有响应,它将进入 catch 块。
这也很有用:#1503
从这个axios issue(感谢zhuyifan2013给出的解决方案),我发现axios timeout
是 响应超时 而不是 连接超时 。
假设您通过 axios 请求了 URL 并且服务器需要很长时间才能响应,在这种情况下 axios超时将起作用。
但是您没有互联网连接或者您请求的 IP 地址或域名不存在,在这种情况下 axios 超时将不起作用。
您必须使用以下代码
const source = CancelToken.source();
const timeout = setTimeout(() => {
source.cancel();
// Timeout Logic
}, 10000);
axios.get(ip + '/config', {cancelToken: source.token}).then((result) => {
// Clear The Timeout
clearTimeout(timeout);
// Handle your response
});
请注意,如果您有有效的连接,超时逻辑 块仍然会被执行。所以你必须清除 timeout
.
submitHashtag = async () => {
const data = await axios.post('/pwa/basics.php', {
withCredentials: true,// if user login
timeout: 30000
})
if (!data) {
// action here
alert('reload window')
return
}
}
感谢@arthankamal,因为他的回答就是解决方案,这只是更新和跟进。
CancelToken 从 v0.22.0 开始弃用,因为他们改用了 AbortController,所以我更新了他的代码。
在此处查看更多信息:https://axios-http.com/docs/cancellation
TrySending(data) {
let abortController = new AbortController()
const timeout = setTimeout(() => {
abortController.abort()
console.log("Aborted")
}, 3000)
return axios
.post(
apiURL,
data,
{ signal: abortController.signal }
)
.then(response => {
clearTimeout(timeout)
return true
})
.catch(error => false)
}
这将 return 是否成功。
一些注意事项:
- 不值得尝试使用 .finally 因为它不起作用
- 如果它被取消,它将直接进入 .catch() 并且错误将是
{ message: 'canceled' }
您可能还需要更新版本的 Node。超时已在 14.14.0 中修复:https://github.com/nodejs/node/pull/34913
我设置了axios.defaults.timeout = 1000;
我停止了向我提供 API 的服务器。
但是发送请求后超时1s多
我的请求是这样的:
import axios from 'axios';
axios.defaults.timeout = 1000;
return axios.post(`${ROOT_URL}/login/${role}`, creds).then((response) => {
console.log(response);
if(response.status === 200) {
// If login was successful, set the token in local storage
localStorage.setItem(`${role}_log_toks`, JSON.stringify(response.data));
// Dispatch the success action
dispatch(receiveLogin(response.data));
return response;
}
}).catch(err => {
console.log(err);
// If there was a problem, we want to
// dispatch the error condition
if(err.data && err.status === 404) {
dispatch(loginError(err.data));
} else {
dispatch(loginError('Please check your network connection and try again.'));
}
return err;
});
我也试过:
return axios.post(`${ROOT_URL}/login/${role}`, creds, {timeout: 1000}).then...
Axios 没有停止抓取,5-10 分钟后它终于显示网络错误。我知道还有其他技术可以处理超时,但为什么 axios 中的超时功能不起作用? axios 不停止获取的原因可能是什么?
编辑: 如评论中所述,我也尝试过:
import axios from 'axios';
const httpClient = axios.create();
httpClient.defaults.timeout = 500;
return httpClient.post(`${ROOT_URL}/login/${role}`, creds)
.then(handleResponse)
您需要创建一个 axios http 客户端的实例:
const httpClient = axios.create();
httpClient.defaults.timeout = 500;
然后您可以按如下方式使用 httpClient:
return httpClient.post(`${ROOT_URL}/login/${role}`, creds)
.then(handleResponse)
附带说明一下,您还可以在同一配置中设置基础 url 而不是使用 ${ROOT_URL}
:
httpClient.defaults.baseURL = ROOT_URL
这段代码对我有用:
axios({
method: "post",
url: 'http://example.com/api',
timeout: 1000 * 5, // Wait for 5 seconds
headers: {
"Content-Type": "application/json"
},
data: {
id: 1234
}
})
.then(response => {
const serverResponse = response.data;
// do sth ...
})
.catch(error => {
console.log(error);
});
如果服务器在 5 秒内没有响应,它将进入 catch 块。
这也很有用:#1503
从这个axios issue(感谢zhuyifan2013给出的解决方案),我发现axios timeout
是 响应超时 而不是 连接超时 。
假设您通过 axios 请求了 URL 并且服务器需要很长时间才能响应,在这种情况下 axios超时将起作用。
但是您没有互联网连接或者您请求的 IP 地址或域名不存在,在这种情况下 axios 超时将不起作用。
您必须使用以下代码
const source = CancelToken.source();
const timeout = setTimeout(() => {
source.cancel();
// Timeout Logic
}, 10000);
axios.get(ip + '/config', {cancelToken: source.token}).then((result) => {
// Clear The Timeout
clearTimeout(timeout);
// Handle your response
});
请注意,如果您有有效的连接,超时逻辑 块仍然会被执行。所以你必须清除 timeout
.
submitHashtag = async () => {
const data = await axios.post('/pwa/basics.php', {
withCredentials: true,// if user login
timeout: 30000
})
if (!data) {
// action here
alert('reload window')
return
}
}
感谢@arthankamal,因为他的回答就是解决方案,这只是更新和跟进。
CancelToken 从 v0.22.0 开始弃用,因为他们改用了 AbortController,所以我更新了他的代码。 在此处查看更多信息:https://axios-http.com/docs/cancellation
TrySending(data) {
let abortController = new AbortController()
const timeout = setTimeout(() => {
abortController.abort()
console.log("Aborted")
}, 3000)
return axios
.post(
apiURL,
data,
{ signal: abortController.signal }
)
.then(response => {
clearTimeout(timeout)
return true
})
.catch(error => false)
}
这将 return 是否成功。
一些注意事项:
- 不值得尝试使用 .finally 因为它不起作用
- 如果它被取消,它将直接进入 .catch() 并且错误将是
{ message: 'canceled' }
您可能还需要更新版本的 Node。超时已在 14.14.0 中修复:https://github.com/nodejs/node/pull/34913