AngularJS $http错误http状态错误

Posted

技术标签:

【中文标题】AngularJS $http错误http状态错误【英文标题】:AngularJS $http wrong http status on error 【发布时间】: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 是否有相同的结果? 【参考方案1】:

根据角源的httpBackend.jsline 63和line 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 前端如何从不同域的后端获取一些数据?

以上是关于AngularJS $http错误http状态错误的主要内容,如果未能解决你的问题,请参考以下文章

405 方法不允许使用 $http 服务 AngularJS

AngularJS $http 从失败的 CORS 请求返回状态码 0

AngularJS 中的 401 未经授权的错误处理

AngularJS $http.POST 方法 405 错误

AngularJS http 中的错误处理然后构造

$http.delete 在 angularJS 中抛出错误