【问题标题】:AngularJS $http wrong http status on errorAngularJS $http错误http状态错误
【发布时间】:2016-09-18 00:20:52
【问题描述】:

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

所以这里是场景:

我调用的 URL 返回 500 Internal Server Error 并带有包含错误消息的 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>

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"
        });
    }
}]);

当您单击“失败”按钮时,返回的状态为 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"
}

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

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

更新:

我构建了一个类似的示例,但使用 GET-Requests 而不是 JSONP,并且效果很好:http://private.peterbagi.de/jsfiddle/ng500status2/

这似乎是 JSONP 特定的问题。尽管如此,它并没有解决我最初的问题,因为我必须处理跨域请求。有什么想法吗?

【问题讨论】:

  • 你看到那个网址了吗?你的BASE_URL 错了
  • 不不,我只是将其删除,因为我不想将其公开...该 URL 存在,如果我在新选项卡中打开它,我也会收到 500 错误并且可以看到响应 json,其中包含一条错误消息。
  • 改成http://localhost 排除这种混淆
  • 很好的提示,谢谢!我改了
  • 您能否提供有关此问题的更多信息?您使用的 AngularJS 版本是什么?使用angular-resource 是否有相同的结果?

标签: angularjs http jsonp


【解决方案1】:

根据角源的httpBackend.jsline 63line 190

“JSONP”请求的状态只能是 -1、404 或 200。

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

更新

在我上面的回答中:

“JSONP”请求的状态只能是 -1、404 或 200。

这表示 Angular 为该请求的响应给出的状态。

XMLHttpRequest是我们在ajax中常用的标准请求类型。它向服务器发送请求并获取响应,因此您可以看到服务器给出的HTTP状态码(200,404,500,401等)一边。

但是,它有一些限制,例如在大多数情况下,您无法进行跨域 XMLHttpRequest(除非您在服务器端设置了 allow-cross-domain 标头)。

这样我们需要JSONP来帮助我们进行跨域请求。事实上,'jsonp' 将 &lt;script&gt; 标记附加到您的文档(在请求完成时始终被删除),其 src 属性是您提供的 URL。

在 Angular 中,将侦听器添加到此 &lt;script&gt; 以跟踪请求的状态。但是,这些监听器只能判断script 是否加载成功。如果成功,则 Angular 将您的响应状态设置为 200。如果没有,则分配 404。这就是状态字段为 404 或 200 的原因,无论服务器实际提供什么。

【讨论】:

  • 我指的是响应,而不是请求,实际上我可以从 Firefox 中看到网络收到了 404 以外的状态码,但在 Angular JS 中,无论如何,响应状态码始终是 404。您能否详细解释一下 JSONP 和 XMLHttpRequest 之间的区别以及它们的响应?
  • @tomriddle_1234 是的,我提到的“状态”正是为了响应。我已经更新了我的答案,希望对您有所帮助。
  • 非常感谢,这让我经历了很多事情,但回到最初的问题,如果 JSONP 请求实际上不能给我来自服务的响应代码,我该如何获得它通过 JSONP 请求-响应?有没有可能?
  • 恐怕不行。脚本元素给出的错误事件除了事件类型的“错误”之外没有显示其他信息。我能想到的唯一解决方法是使用像 json-rpc 这样的协议,使每个响应都成功并将实际状态代码包装在响应正文中。但这似乎不切实际,因为如果您可以修改服务器,您就没有理由使用 jsonp 而不是 xhr?
  • 我选择 JSONP 的原因是我遇到的跨域资源共享问题,如果我只使用 GET,它会一直报 CORS 错误。一些资源表明我可以改用 JSONP,但现在它显然不合适。事实上,我可以控制我的 Phalcon 后端,它位于不同的域中,因为我知道将前端和后端分开是件好事。我打算制作一个 RESTful API,我相信那里没有问题,并且所有标题都在 .htaccess 文件中正确设置,那么 AngularJS 前端如何从不同域的后端获取一些数据?
猜你喜欢
  • 2013-04-26
  • 1970-01-01
  • 1970-01-01
  • 2015-01-24
  • 2017-03-13
  • 2018-11-18
  • 2021-06-19
  • 2016-07-15
  • 2019-09-13
相关资源
最近更新 更多