axios 库中的超时功能不起作用
Posted
技术标签:
【中文标题】axios 库中的超时功能不起作用【英文标题】:Timeout feature in the axios library is not working 【发布时间】:2016-08-09 23:35:08 【问题描述】:我已经设置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 不停止获取的原因可能是什么?
Axios version 0.9.1
编辑: 如cmets中所述,我也尝试过:
import axios from 'axios';
const httpClient = axios.create();
httpClient.defaults.timeout = 500;
return httpClient.post(`$ROOT_URL/login/$role`, creds)
.then(handleResponse)
【问题讨论】:
【参考方案1】:从这个axios issue(感谢zhuyifan2013提供解决方案),我发现axiostimeout
是响应超时 不是连接超时。
假设您通过 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 Logic 块。所以你必须清除timeout
。
【讨论】:
如果您在使用 Angular 时遇到此问题,我想添加,您可以将.pipe(timeout(TIMEOUT_MILLIS))
添加到 observable。
axios 使用 XMLHttpRequest 作为浏览器环境,如果 > 但你没有互联网连接 - 这将是一个 net::ERR_INTERNET_DISCONNECTED,所以我认为没有真正需要使用 axios (或任何其他)超时。它仅适用于 nodejs env。浏览器可以做的所有其他事情。所以如果你真的想设置一个连接超时,你可以尝试从 axios 获取一个请求对象并检查 readyState——直到它打开(1)——它还没有连接。
我不明白他们为什么不只是在库中实现它,而不是给我们一个损坏的超时选项。他们只是关闭了问题而不修复它......
如果服务器关闭了,axios超时是否有效【参考方案2】:
此代码适用于我:
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
【讨论】:
【参考方案3】:你需要创建一个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
【讨论】:
1.我想你想返回 httpClient.post($ROOT_URL/login/$role
, creds) 2. 也试过了。没用。 3. 目前,我在这里使用了 mislav 提到的一种技术:github.com/github/fetch/issues/175 就像一个魅力,但我希望 axios 提供的超时工作。
我不知道为什么这对你不起作用。您使用的是哪个版本的axios
?可以在上面包含你的require
/import
语句和axios初始化代码吗?【参考方案4】:
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
【讨论】:
虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review @DanielCottone 请仔细查看。这也是一个答案 它有效,但是当我设置超时:999999 时出现错误:当我设置的超时大于 5000 时,出现“net::ERR_CONNECTION_REFUSED”而不是“超过 999999 毫秒的超时”【参考方案5】:向@arthankamal 致敬,因为他的回答就是解决方案,这只是更新和跟进。
从 v0.22.0 开始不推荐使用 CancelToken,因为他们切换到 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)
无论成功与否都会返回。
一些注意事项:
不值得尝试使用 .finally,因为它不起作用 如果它被取消,它将直接转到 .catch(),错误将是 message: 'canceled'
【讨论】:
【参考方案6】:我在使用本机反应时遇到了这个问题。解决办法是:
-
创建一个文件“CustomClientFactory.java”并把这段代码放在上面:
package <your package name>; import com.facebook.react.modules.network.OkHttpClientFactory; import com.facebook.react.modules.network.OkHttpClientProvider; import com.facebook.react.modules.network.ReactCookieJarContainer; import java.util.Arrays; import okhttp3.OkHttpClient; import okhttp3.Protocol; import java.util.concurrent.TimeUnit; public class CustomClientFactory implements OkHttpClientFactory @Override public OkHttpClient createNewNetworkModuleClient() return new OkHttpClient.Builder() .connectTimeout(100000, TimeUnit.MILLISECONDS) .readTimeout(100000, TimeUnit.MILLISECONDS) .writeTimeout(100000, TimeUnit.MILLISECONDS) .cookieJar(new ReactCookieJarContainer()) .protocols(Arrays.asList(Protocol.HTTP_1_1)) .build();
-
然后在 MainApplication.java 中的“onCreate”方法中添加以下代码:
OkHttpClientProvider.setOkHttpClientFactory(new CustomClientFactory());
你可以在下面的链接中完整解释超时:
timeout in android
【讨论】:
你们为什么要在javascript
标签下发布android / java 的东西?这不一样...以上是关于axios 库中的超时功能不起作用的主要内容,如果未能解决你的问题,请参考以下文章
使用 axios 响应中的操作改变 vuex 存储状态 - 提交不起作用