AngularJS $http 错误 http 状态错误
AngularJS $http wrong http status on error
我正在尝试使用 AngularJS 的 $http 服务构建一个 JSONP 请求,但出现错误时,我得到错误的 http 状态代码 404 而不是 500,页面正文是也不见了。
场景是这样的:
我正在调用 returns 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>
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 网络面板中,您会看到正确的响应代码 (500),我希望在 Angular 输出中看到相同的结果。
为什么会这样或者我做错了什么?
更新:
我构建了一个类似的示例,但使用 GET-Requests 而不是 JSONP,并且效果很好:http://private.peterbagi.de/jsfiddle/ng500status2/
这似乎是一个 JSONP 特定的问题。尽管如此,它并没有解决我最初的问题,因为我必须处理跨域请求。有什么想法吗?
根据 angular 来源的 httpBackend.js line 63 and line 190,
'JSONP' 请求的状态只能是 -1、404 或 200。
原因是 angular 'JSONP' 中的请求不是 XMLHttpRequest。 AFAIK 无法以这种方式处理特定的错误代码。 javascript 唯一知道的是这个请求是否成功。
更新:
在我上面的回答中:
the status of a 'JSONP' request can only be -1, 404, or 200.
这意味着angular为响应此请求而给出的状态。
XMLHttpRequest 是我们常用的标准请求类型 ajax.It 向服务器发送请求并获取响应所以你可以看到 HTTP 状态码(200,404,500,401,等)由服务器端给出。
但是,它有一些限制,比如在大多数情况下你不能创建 cross-domain XMLHttpRequest(除非你设置了 allow-cross-domain
header 在服务器端)。
这样我们就需要JSONP来帮助我们进行cross-domain请求。事实上 'jsonp' 是将 <script>
标签附加到您的文档(请求完成时总是删除),其 src
属性是您提供的 URL。
在 angular 中,侦听器被添加到此 <script>
以跟踪请求的状态。但是,这些侦听器只能判断 script
是否加载成功。如果成功,angular 将您的响应状态设置为 200。否则,分配 404。这就是为什么状态字段是 404 或 200,而不管服务器实际提供什么。
我正在尝试使用 AngularJS 的 $http 服务构建一个 JSONP 请求,但出现错误时,我得到错误的 http 状态代码 404 而不是 500,页面正文是也不见了。
场景是这样的:
我正在调用 returns 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>
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 网络面板中,您会看到正确的响应代码 (500),我希望在 Angular 输出中看到相同的结果。
为什么会这样或者我做错了什么?
更新:
我构建了一个类似的示例,但使用 GET-Requests 而不是 JSONP,并且效果很好:http://private.peterbagi.de/jsfiddle/ng500status2/
这似乎是一个 JSONP 特定的问题。尽管如此,它并没有解决我最初的问题,因为我必须处理跨域请求。有什么想法吗?
根据 angular 来源的 httpBackend.js line 63 and line 190,
'JSONP' 请求的状态只能是 -1、404 或 200。
原因是 angular 'JSONP' 中的请求不是 XMLHttpRequest。 AFAIK 无法以这种方式处理特定的错误代码。 javascript 唯一知道的是这个请求是否成功。
更新:
在我上面的回答中:
the status of a 'JSONP' request can only be -1, 404, or 200.
这意味着angular为响应此请求而给出的状态。
XMLHttpRequest 是我们常用的标准请求类型 ajax.It 向服务器发送请求并获取响应所以你可以看到 HTTP 状态码(200,404,500,401,等)由服务器端给出。
但是,它有一些限制,比如在大多数情况下你不能创建 cross-domain XMLHttpRequest(除非你设置了 allow-cross-domain
header 在服务器端)。
这样我们就需要JSONP来帮助我们进行cross-domain请求。事实上 'jsonp' 是将 <script>
标签附加到您的文档(请求完成时总是删除),其 src
属性是您提供的 URL。
在 angular 中,侦听器被添加到此 <script>
以跟踪请求的状态。但是,这些侦听器只能判断 script
是否加载成功。如果成功,angular 将您的响应状态设置为 200。否则,分配 404。这就是为什么状态字段是 404 或 200,而不管服务器实际提供什么。