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 和功能的 Vue.js 代码不起作用

将道具值传递给axios中的url不起作用

Axios删除不起作用

使用 axios 响应中的操作改变 vuex 存储状态 - 提交不起作用

rails api,react前端,axios,开发中的CORS不起作用

为啥我使用 redux 时 axios.get 不起作用?