AngularJS $ http错误的http状态出错

bug*_*985 7 jsonp http angularjs

我正在尝试使用AngularJS的$ http服务构建JSONP请求,并且在出现错误时我得到错误的http状态代码404而不是500,并且页面正文也丢失了.

所以这是场景:

我正在调用的URL返回500内部服务器错误,其中包含错误消息的JSON输出:

http://private.peterbagi.de/jsfiddle/ng500status/api.php?code=500&callback=test

index.html
(见行动:http://private.peterbagi.de/jsfiddle/ng500status/)

<!DOCTYPE HTML>
<html lang="en-US">
<head>
    <meta charset="UTF-8">
    <title></title>
    <script src= "//ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
    <script src= "app.js"></script>
</head>
<body ng-app="app" ng-controller="UploadController">
    <button ng-click="upload(200)" value="OK">OK</button>
    <button ng-click="upload(500)" value="Fail">Fail</button>
    <pre>{{response | json}}</pre>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

app.js

var app = angular.module('app', []);

app.constant('BASE_URL','http://private.peterbagi.de/jsfiddle/ng500status/');

app.controller("UploadController", ['$scope','Upload','BASE_URL',
    function($scope,Upload,BASE_URL) {

    $scope.upload = function(code) {

        Upload(code).then( function(response) {
                $scope.response = response;
            }, function(error) {
                $scope.response = error;
            } );
    }
}]);

app.factory('Upload', ['$http','BASE_URL', function($http,BASE_URL) {
    return function (code) {
        var callUrl = BASE_URL + "api.php?code="+code;
        return $http({
            method: 'JSONP',
            url : callUrl+"&callback=JSON_CALLBACK"
        });
    }
}]);
Run Code Online (Sandbox Code Playgroud)

单击"失败"按钮时,返回的状态为404,并且响应正文也丢失.

产量

{
  "status": 404,
  "config": {
    "method": "JSONP",
    "transformRequest": [
      null
    ],
    "transformResponse": [
      null
    ],
    "url": "http://private.peterbagi.de/jsfiddle/ng500status/api.php?code=500&callback=JSON_CALLBACK",
    "headers": {
      "Accept": "application/json, text/plain, */*"
    }
  },
  "statusText": "error"
}
Run Code Online (Sandbox Code Playgroud)

在Chrome DevTools Network面板中,您会看到正确的响应代码(500),我希望在Angular输出中看到相同的结果.

为什么会发生这种情况或者我做错了什么?

更新:

我构建了一个类似的例子,但使用GET-Requests而不是JSONP,它运行良好:http://private.peterbagi.de/jsfiddle/ng500status2/

这似乎是JSONP特定的问题.然而,它并没有解决我最初的问题,因为我必须使用跨域请求.有任何想法吗?

MMh*_*ter 8

根据角度源的httpBackend.js 第63 行和第190行,

"JSONP"请求的状态只能是-1,404或200.

原因是角度'JSONP'请求不是XMLHttpRequest.AFAIK无法以这种方式处理特定的错误代码.javascript知道的唯一事情就是这个请求是否成功.

更新:

在上面的答案中:

"JSONP"请求的状态只能是-1,404或200.

这意味着由此请求的响应以角度给出的状态.

XMLHttpRequest的是我们通常在ajax.It用于发送请求到服务器,并获取响应,以便可以看到的HTTP状态代码的标准请求类型(200404500401等)通过服务器侧给出.

但是,它有一些限制,就像大多数情况下你不能创建跨域XMLHttpRequest(除非你allow-cross-domain在服务器端设置了标头).

通过这种方式,我们需要JSONP来帮助我们进行跨域请求.事实上,'jsonp'会<script>在文档中附加标记(在请求完成时始终会删除),其src属性是您提供的URL.

在角度中,将向其添加侦听器<script>以跟踪请求的状态.但是,这些侦听器只能判断是否script成功加载.如果成功,则角度将响应的状态设置为200.如果不成功,则分配404.这就是为什么状态字段是404或200,无论服务器实际给出了什么.