超时和$ http.get中何时发生中止?

时间:2017-11-21 09:24:45

标签: javascript angularjs ajax xmlhttprequest timeout

AngularJS 1.6.6 has支持区分XHR完成,错误,中止,超时,我有这个代码片段,它向下面的URL发出请求:

$http.get(url, {timeout: 1000})
  .then(...)
  .catch(function(error) {
       console.log(error.xhrStatus) // could be abort, complete, error and timeout
   });

当请求我的api需要超过1秒时,承诺被xhrStatus'abort'拒绝,我想知道在什么情况下我会得到'超时'和'错误'状态文本?

编辑:如果答案在Web Api中提供相关的服务器端代码,那将会很棒

1 个答案:

答案 0 :(得分:3)

"超时"因为$ httpBackend中的xhr永远不会有超时属性设置而非使用它自己的机制来中止xhr请求(如果超时ms到期或者在解析中传递了承诺),我将永远不会发生这种情况。 / p>

https://github.com/angular/angular.js/blob/master/src/ng/httpBackend.js#L165

"错误"如果已分派请求并且网络连接已关闭,则会发生

如果500或200返回,状态将完成,但angular将触发http promise上的成功或错误/捕获处理程序,具体取决于状态代码。

测试结果模型(注意我断开网络以获取test3.php的结果,加载了test.html页面,然后在setTimeout触发get之前断开了网络,因此强制xhr.status出错)

{
  "msg1": {
    "data": {
      "val": "test"
    },
    "status": 200,
    "config": {
      "method": "GET",
      "transformRequest": [
        null
      ],
      "transformResponse": [
        null
      ],
      "jsonpCallbackParam": "callback",
      "timeout": 1000,
      "url": "test1.php",
      "headers": {
        "Accept": "application/json, text/plain, */*"
      }
    },
    "statusText": "OK",
    "xhrStatus": "complete"
  },
  "msg2": {
    "data": null,
    "status": -1,
    "config": {
      "method": "GET",
      "transformRequest": [
        null
      ],
      "transformResponse": [
        null
      ],
      "jsonpCallbackParam": "callback",
      "timeout": 1,
      "url": "test2.php",
      "headers": {
        "Accept": "application/json, text/plain, */*"
      }
    },
    "statusText": "",
    "xhrStatus": "abort"
  },
  "msg3": {
    "data": null,
    "status": -1,
    "config": {
      "method": "GET",
      "transformRequest": [
        null
      ],
      "transformResponse": [
        null
      ],
      "jsonpCallbackParam": "callback",
      "url": "test3.php",
      "headers": {
        "Accept": "application/json, text/plain, */*"
      }
    },
    "statusText": "",
    "xhrStatus": "error"
  },
  "msg4": {
    "data": "",
    "status": 500,
    "config": {
      "method": "GET",
      "transformRequest": [
        null
      ],
      "transformResponse": [
        null
      ],
      "jsonpCallbackParam": "callback",
      "url": "test4.php",
      "headers": {
        "Accept": "application/json, text/plain, */*"
      }
    },
    "statusText": "Internal Server Error",
    "xhrStatus": "complete"
  }
}

的test.html

<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.js"></script>
<script>
angular.module('myApp', [])
  .controller('MyCtrl', function($http){
    var url1 = "test1.php";
    var url2 = "test2.php";
    var url3 = "test3.php";
    var url4 = "test4.php";

    var ctrl = this;

    ctrl.model={msg1:null, msg2:null, msg3:null, msg4:null}

    $http.get(url1, {timeout: 1000})
      .then(function(resp){
        ctrl.model.msg1 = resp
      })
      .catch(function(error) {
        ctrl.model.msg1 = error;
      });

    $http.get(url2, {timeout: 1})
      .then(function(resp){
        ctrl.model.msg2 = resp
      })
      .catch(function(error) {
        ctrl.model.msg2 = error;
      });
    setTimeout(function(){
    $http.get(url3)
      .then(function(resp){
        ctrl.model.msg3 = resp
      })
      .catch(function(error) {
        ctrl.model.msg3 = error;
      });
    }, 2000);
    $http.get(url4)
      .then(function(resp){
        ctrl.model.msg4 = resp
      })
      .catch(function(error) {
        ctrl.model.msg4 = error;
      });


  });
</script>

</head>
<body ng-app="myApp" ng-controller="MyCtrl as myCtrl">
<pre>{{myCtrl.model|json}}</pre>
</body>
</html>

test1.php

<?php
echo "{\"val\":\"test\"}";

test2.php

<?php
sleep(10);

test3.php

<?php
sleep(1000);

test4.php

<?php
throw new Exception("Error");