Ich denke, dafür gibt es tatsächlich einen Grund. Der Server hat normalerweise schnelle und langsame Endpunkte, und ich denke, das eckige Team wollte nicht, dass jeder das langsamstmögliche Timeout hat, selbst für Anrufe, die normalerweise schnell sein sollten
OlivierM
1
Sie können einen Dienst erstellen, der http-Anforderungen ausführt, Methoden, URLs und Daten sendet und darin die gewünschten Standardkonfigurationen implementiert. Es ist auch besser, die Domäne der URL einzuschließen und nur den Rest der URL zu übergeben, und sie werden angehängt die vollständige URL
Mohamed Selim
1
wie man Timeout für Post-Methode $http.post('path/to/service', {data:data});
einstellt
Antworten:
41
AKTUALISIERT : $ http berücksichtigt nicht die Standardeinstellung für das in httpProvider festgelegte Zeitlimit (siehe Kommentare). Mögliche Problemumgehung: https://gist.github.com/adnan-i/5014277
Sind Sie sicher, dass der obige Code funktioniert? Es sieht so aus, als ob das config.timeout beim Aufruf von sendReq nicht geändert wird: github.com/angular/angular.js/blob/master/src/ng/http.js#L550 Vergleichen Sie mit den Standardeinstellungen.mitCredentials einige Zeilen darüber wird auf die Standardeinstellung zurückgreifen.
Orjan
@orjan Nun, das oben genannte funktioniert nicht von selbst, wenn Sie danach fragen. Der Code zeigt nur eine Konfigurationsoption für Ihr eigenes Angular-Projekt. Weitere Informationen finden Sie in den Abschnitten "Festlegen von HTTP-Headern" und "Parameter" unter docs.angularjs.org/api/ng.$http
Stewie,
1
Mir ist das Konfigurationsbeispiel bekannt und ich weiß, dass der Code nicht alleine ausgeführt wird. Mir sind auch die Standardeinstellungen für Header und withCredentials bekannt. Aber ich glaube nicht, dass die Standardeinstellungen für das Timeout funktionieren. Ich habe eine jsfiddle erstellt: jsfiddle.net/RYDMM/4, die versucht, das Problem zu reproduzieren, aber es sieht so aus, als ob das Timeout jsonp überhaupt nicht beeinflusst
orjan
Hier ist eine Zusammenfassung, die zu erklären versucht, dass es nicht möglich ist, eine Standardzeitüberschreitung festzulegen
orjan
2
@orjan Du hast absolut recht. Ich habe mich auf die Dokumentation verlassen, um die Antwort zu geben, aber dies beweist erneut, dass Angular-Dokumente nicht als verlässlich anzusehen sind. Nachdem ich mir die Quelle angesehen habe ( github.com/angular/angular.js/blob/master/src/ng/http.js#L759 ), kann ich Ihre Ergebnisse bestätigen - es ist nicht möglich, mit $ httpProvider ein globales Timeout festzulegen. Standardeinstellungen. Vielen Dank, Orjan, für Ihren Fleiß. Ich werde meine Antwort aktualisieren, um meine Problemumgehung
Stewie
105
Dies ist mit blutenden Angular.js möglich (getestet mit Git Master 4ae46814ff).
Sie können den Request http Interceptor verwenden. So was.
Funktioniert wie ein Zauber und sollte die akzeptierte Antwort sein, da es jetzt 2 Jahre später ist ....
Sebastian J.
2
Warum injizieren Sie aus Interesse $ rootScope und $ q? oder werden diese außerhalb des eingefügten Codes verwendet?
Ben Taliadoros
1
Wie gehen Sie damit um? Ich stelle fest, dass die Anfrage storniert wurde. Kann ich einen Listener dafür einstellen?
Ben Taliadoros
Die beste Antwort, die von der aktuellen Version nicht vollständig unterstützt wird. Bitte aktualisieren Sie Ihre Antwort, indem Sie die erste Zeile entfernen, in der es um die eckige Version geht
Nicolas Janel
5
config.timeout = config.timeout || 10000;
Alexander Atanasov
9
Danke für den Beitrag und das Update !!
Bei der Untersuchung dieses Problems speziell für $resourcedachte ich, ich würde näher auf das eingehen, was ich gefunden habe:
Dieses Problem wurde im Tracker protokolliert und in Winkel 1.1.5 wird die Weitergabe der Timeout-Eigenschaft an die $httpAnforderung unterstützt:
Für diejenigen von uns in früheren Versionen, insbesondere ich verwende Angular 1.0.6, ist es möglich, die Quelldatei für angle-resource.js in Zeile 396 zu bearbeiten. Dort finden Sie den Aufruf, $httpwo Sie die Timeout-Eigenschaft für alle selbst hinzufügen können Ressourcenanforderungen.
Da es nicht erwähnt wurde und ich die Lösung von Stewie testen musste, wird bei einem Timeout das Argument 'status' überprüft, um zwischen einem Fehler und einem Abbruch / Timeout zu unterscheiden. Es wird 0für Zeitüberschreitungen zurückkehren, anstatt zu sagen 404:
Da es nur wenige Fälle gibt, in denen ich ein Zeitlimit verwenden muss, anstatt es global festzulegen, verpacke ich die Anforderungen in eine $timeoutFunktion wie folgt:
//errorHandler gets called wether it's a timeout or resource call failsvar t = $timeout(errorHandler, 5000);
myResource.$get( successHandler, errorHandler )
functionsuccessHandler(data){
$timeout.cancel(t);
//do something with data...
}
functionerrorHandler(data){
//custom error handle code
}
+! für "die Art und Weise, zwischen einem Fehler und einem Abbruch / Timeout zu unterscheiden"
Bennett McElwee
1
Ich habe die gleiche Anforderung und verwende AngularJS 1.0.7. Ich habe mir den folgenden Code ausgedacht, da keine der oben genannten Lösungen für mich machbar erscheint (machbar in dem Sinne, dass das Timeout an einem Ort global sein soll). Grundsätzlich ich bin Maskierung der ursprünglichen http $ Methoden und Hinzufügen timeoutfür jede $httpAnforderung und andere zwingende Verknüpfung Methoden, wie get, post... so dass sie die neuen maskiert verwenden werden $http.
$http.post('path/to/service', {data:data});
Antworten:
AKTUALISIERT : $ http berücksichtigt nicht die Standardeinstellung für das in httpProvider festgelegte Zeitlimit (siehe Kommentare). Mögliche Problemumgehung: https://gist.github.com/adnan-i/5014277
Ursprüngliche Antwort:
angular.module('MyApp', []) .config(['$httpProvider', function($httpProvider) { $httpProvider.defaults.timeout = 5000; }]);
quelle
Dies ist mit blutenden Angular.js möglich (getestet mit Git Master 4ae46814ff).
Sie können den Request http Interceptor verwenden. So was.
angular.module('yourapp') .factory('timeoutHttpIntercept', function ($rootScope, $q) { return { 'request': function(config) { config.timeout = 10000; return config; } }; });
Und dann in .config $ httpProvider injizieren und dies tun:
$httpProvider.interceptors.push('timeoutHttpIntercept');
quelle
Danke für den Beitrag und das Update !!
Bei der Untersuchung dieses Problems speziell für
$resource
dachte ich, ich würde näher auf das eingehen, was ich gefunden habe:$http
Anforderung unterstützt:https://github.com/angular/angular.js/issues/2190 http://code.angularjs.org/1.1.5/docs/api/ngResource.$resource
Für diejenigen von uns in früheren Versionen, insbesondere ich verwende Angular 1.0.6, ist es möglich, die Quelldatei für angle-resource.js in Zeile 396 zu bearbeiten. Dort finden Sie den Aufruf,
$http
wo Sie die Timeout-Eigenschaft für alle selbst hinzufügen können Ressourcenanforderungen.Da es nicht erwähnt wurde und ich die Lösung von Stewie testen musste, wird bei einem Timeout das Argument 'status' überprüft, um zwischen einem Fehler und einem Abbruch / Timeout zu unterscheiden. Es wird
0
für Zeitüberschreitungen zurückkehren, anstatt zu sagen404
:$http.get("/home", { timeout: 100 }) .error(function(data, status, headers, config){ console.log(status) }
Da es nur wenige Fälle gibt, in denen ich ein Zeitlimit verwenden muss, anstatt es global festzulegen, verpacke ich die Anforderungen in eine
$timeout
Funktion wie folgt://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 }
quelle
Ich habe die gleiche Anforderung und verwende AngularJS 1.0.7. Ich habe mir den folgenden Code ausgedacht, da keine der oben genannten Lösungen für mich machbar erscheint (machbar in dem Sinne, dass das Timeout an einem Ort global sein soll). Grundsätzlich ich bin Maskierung der ursprünglichen http $ Methoden und Hinzufügen
timeout
für jede$http
Anforderung und andere zwingende Verknüpfung Methoden, wieget
,post
... so dass sie die neuen maskiert verwenden werden$http
.JSFiddle für folgenden Code:
/** * @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; }]); }]); })();
Fügen Sie die Abhängigkeit vom obigen Modul hinzu und konfigurieren Sie das Zeitlimit durch Konfigurieren
ngx$httpTimeoutProvider
wie folgt: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) } ]);
quelle