如何在AngularJs中设置全局http超时

如何在AngularJs中设置全局http超时,angularjs,Angularjs,我知道我每次都可以设置超时: $http.get('path/to/service', {timeout: 5000}); 。。。但我想设置一个全局超时以保持代码干燥。已更新。:$http将不遵守在httpProvider中设置超时的默认设置(请参阅注释)。可能的解决办法: 原始答复: angular.module('MyApp', []) .config(['$httpProvider', function($httpProvider) { $httpProvider.defau

我知道我每次都可以设置超时:

$http.get('path/to/service', {timeout: 5000});

。。。但我想设置一个全局超时以保持代码干燥。

已更新。:$http将不遵守在httpProvider中设置超时的默认设置(请参阅注释)。可能的解决办法:

原始答复:

angular.module('MyApp', [])
  .config(['$httpProvider', function($httpProvider) {
    $httpProvider.defaults.timeout = 5000;
}]);

这可以通过bleendge angular.js实现(使用git master 4ae46814ff进行测试)

您可以使用请求http拦截器。像这样

 angular.module('yourapp')
  .factory('timeoutHttpIntercept', function ($rootScope, $q) {
    return {
      'request': function(config) {
        config.timeout = 10000;
        return config;
      }
    };
 });
然后在.config中注入$httpProvider并执行以下操作:

$httpProvider.interceptors.push('timeoutHttpIntercept');

谢谢你的帖子和更新

在专门为
$resource
研究这个问题时,我想我应该详细阐述一下我的发现:

  • 此问题记录在跟踪器中,在angular 1.1.5中,支持将超时属性传递给
    $http
    请求:

  • 对于我们这些早期版本的人,特别是我使用的angular 1.0.6,可以在第396行编辑angular-resource.js的源文件,您可以找到对
    $http
    的调用,您可以自己为所有资源请求添加超时属性

  • 由于没有提到它,我不得不测试Stewie的解决方案,当超时确实发生时,区分错误和中止/超时的方法是检查“status”参数。对于超时,它将返回
    0
    ,而不是说
    404

    $http.get("/home", { timeout: 100 })
    .error(function(data, status, headers, config){
            console.log(status)
        }
    
  • 因为只有少数情况下我需要使用超时而不是全局设置超时,所以我将请求包装在
    $timeout
    函数中,如下所示:

    //errorHandler gets called wether it's a timeout or resource call fails
    
    var t = $timeout(errorHandler, 5000);
    myResource.$get( successHandler, errorHandler )   
    function successHandler(data){
        $timeout.cancel(t);
        //do something with data...
    }
    
    function errorHandler(data){
        //custom error handle code
    } 
    

我有同样的要求,我正在使用AngularJS 1.0.7。我提出了下面的代码,因为上面的解决方案对我来说都不可行(从某种意义上说,我希望超时在一个地方是全局的)。基本上,我屏蔽了原始的$http方法,为每个
$http
请求添加
timeout
,并覆盖其他快捷方式方法,如
get
post
。。。这样他们就可以使用新的掩码
$http

有关以下代码:

/**
 * @name ngx$httpTimeoutModule
 * @description Decorates AngularJS $http service to set timeout for each
 * Ajax request.
 * 
 * Implementation notes: replace this with correct approach, once migrated to Angular 1.1.5+
 * 
 * @author Manikanta G
 */
;(function () {
    'use strict';

    var ngx$httpTimeoutModule = angular.module('ngx$httpTimeoutModule', []);

    ngx$httpTimeoutModule.provider('ngx$httpTimeout', function () {
        var self = this;
        this.config = {
            timeout: 1000 // default - 1 sec, in millis
        };

        this.$get = function () {
            return {
                config: self.config
            };
        };
    });

    /** 
     * AngularJS $http service decorator to add timeout
     */
    ngx$httpTimeoutModule.config(['$provide',  function($provide) {

        // configure $http provider to convert 'PUT', 'DELETE' methods to 'POST' requests
        $provide.decorator('$http', ['$delegate', 'ngx$httpTimeout', function($http, ngx$httpTimeout) {
            // create function which overrides $http function

            var _$http = $http;

            $http = function (config) {
                config.timeout = ngx$httpTimeout.config.timeout;
                return _$http(config);
            };
            $http.pendingRequests = _$http.pendingRequests;
            $http.defaults = _$http.defaults;

            // code copied from angular.js $HttpProvider function
            createShortMethods('get', 'delete', 'head', 'jsonp');
            createShortMethodsWithData('post', 'put');

            function createShortMethods(names) {
                angular.forEach(arguments, function(name) {
                    $http[name] = function(url, config) {
                        return $http(angular.extend(config || {}, {
                            method : name,
                            url : url
                        }));
                    };
                });
            }

            function createShortMethodsWithData(name) {
                angular.forEach(arguments, function(name) {
                    $http[name] = function(url, data, config) {
                        return $http(angular.extend(config || {}, {
                            method : name,
                            url : url,
                            data : data
                        }));
                    };
                });
            }

            return $http;
        }]);

    }]);

})();
添加对上述模块的依赖关系,并通过配置ngx$httpTimeoutProvider来配置超时,如下所示:

angular.module('App', ['ngx$httpTimeoutModule']).config([ 'ngx$httpTimeoutProvider', function(ngx$httpTimeoutProvider) {
    // config timeout for $http requests
    ngx$httpTimeoutProvider.config.timeout = 300000; // 5min (5 min * 60 sec * 1000 millis)

} ]);

您确定上面的代码正在工作吗?调用sendReq:Compare with defaults.withCredentials(与默认值比较)时,config.timeout似乎没有被修改。如果上面有几行,这将返回到默认值。@或者,如果您是这样问的,那么上面的内容本身就不起作用。代码只是显示了您自己的角度项目的配置选项。有关更多信息,您可以查看“设置HTTP头”和“参数”部分,我知道它的配置示例,并且代码没有单独运行。我还知道header和withCredentials的默认值。但我不认为默认值在超时时起作用。我已经创建了一个JSFIDLE:试图重现这个问题,但看起来超时根本不会影响jsonp这里有一个要点试图解释不可能设置默认超时:@orjan You是绝对正确的。我依赖于提供答案的文档,但这再次证明了角度文档是不可依赖的。查看源代码()后,我可以确认您的发现-不可能使用$httpProvider.defaults设置全局超时。谢谢奥扬,谢谢你的勤奋。我将更新我的答案以提供解决方案:+!对于“区分错误和中止/超时的方法”,我认为这实际上是有原因的。服务器通常有快端点和慢端点,我猜angular团队不希望每个人都有尽可能慢的超时,即使对于通常应该是快的调用,也不希望每个人都有尽可能慢的超时。您可以创建一个执行http请求的服务,发送它方法,url和数据及其内部实现您想要的任何默认配置。最好包括url的域,并只传递url的其余部分,然后附加它们,形成完整的url如何为post方法设置超时
$http.post('path/to/service',{data:data})就像一个魅力,应该是被接受的答案,因为现在已经过了2年了……出于兴趣,你为什么要注入$rootScope和$q?或者这些是在你粘贴的代码之外使用的吗?还有,你是如何处理的?我注意到请求被取消了,我可以为此设置一个侦听器吗?实际版本不完全支持最佳答案。请删除讨论角度版本的第一行config.timeout=config.timeout | | 10000;