在一个Angular客户端中预飞行失败,但在另一个客户端中没有



我使用个人帐户身份验证模板创建了一个WebApi应用程序,并启用了CORS以允许各种客户端使用我的服务。我将CORS配置为允许所有原点("*")。我还创建了一个Angular前端,它成功地检索了一个令牌,以便在调用安全路由时使用。但是,由于飞行前检查失败,客户端无法调用注销操作。

在对该问题进行故障排除时,我使用本文中的说明创建了一个单独的解决方案。新的解决方案效果很好,所以我把新解决方案的客户指向了我原来的WebApi项目,它也很好。这让我相信Angular客户之间有一些不同,但我还没有发现显著的差异。

有人能回顾一下下面的代码,指出工作的客户端和失败的客户端之间的区别吗?

这是应用程序中工作的Angular代码:

应用程序配置

app.config(['$httpProvider', function ($httpProvider) {
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
// Override $http service's default transformRequest
$httpProvider.defaults.transformRequest = [function (data) {
// Converts an object to x-www-form-urlencoded serialization.
}];
}]);

在我的工厂

var deferred = $q.defer();
$http({
method: 'POST',
url: logoutUrl,
headers: getHeaders(),
}).then(function (data, status, headers, cfg) {
accessToken = null;
deferred.resolve({ status: 'success' });
}, function (err, status) {
console.log(err);
deferred.reject(status);
});
return deferred.promise;
function getHeaders() {
if (accessToken) {
return { "Authorization": "Bearer " + accessToken };
}
}

这是通过的原始HTTP请求。OPTIONS飞行前检查通过,因此POST通过。

OPTIONS http://localhost:56508/api/Account/Logout HTTP/1.1
Host: localhost:56508
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://localhost:42458
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
Access-Control-Request-Headers: authorization
Accept: */*
DNT: 1
Referer: http://localhost:42458/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8
POST http://localhost:56508/api/Account/Logout HTTP/1.1
Host: localhost:56508
Connection: keep-alive
Content-Length: 0
Accept: application/json, text/plain, */*
Origin: http://localhost:42458
Authorization: Bearer fNKcX_jCNhQuIhorMw-QPyezReQJd5ehoVhqegUmSQZxdbHp-T6L4RPehSl6ihSpNbYH58uhELwNHV0bEAyRj0G7bmFv4O5GIqBDyiOIB-YBfez5zHRNHbMe_iTdtBwdgOdbLh5PNSNIOi4ffU6H-py4oko0rMkLSP_hFSl2TGcbJwuJkrmHmahmLyeyQ-OO8KI4Kc-WoTaIVw3dJ5LDxbdSFF9aWoaCVGDfbP1tcp-aTMmydqZLnkX5DAGQPDawsiuXuWuwvUDPz6f4K5F78r4D8ldl8cCSO0uniSv3mIZYbgDuzwfjIrV_lN5pFYHg38f-7RcwvE-TARr0wJ1dNcM9XnNTJRXxsJRpJP-LAG369smEnRk2Z2D7Gds0KCAK7zKcwRyJh8u7_YCLcMVJR97mhJk-n4zEfnD3yxa0VsiNHkHiAAjtXF78ASWBW2LXXYlvn0Mu0tcltZ7Qur9-TslHjUhD1BmNkQzwTkQte3kbMk7HsCDZCWaxr-j_8ApD
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
DNT: 1
Referer: http://localhost:42458/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8

这是应用程序中失败的Angular代码:

在我的工厂

var deferred = $q.defer();
$http({
method: 'POST',
url: logoutUrl,
headers: {
'Authorization': 'Bearer ' + accessToken
,'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
},
}).then(function (data, status, headers, cfg) {
accessToken = null;
deferred.resolve({ status: 'success' });
}, function (err, status) {
console.log(err);
deferred.reject(status);
});
return deferred.promise;

这是通过的原始HTTP请求。OPTIONS飞行前检查在此失败,因此POST无法通过。

OPTIONS http://localhost:56508/api/Account/Logout HTTP/1.1
Host: localhost:56508
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://localhost:45743
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
Access-Control-Request-Headers: authorization
Accept: */*
DNT: 1
Referer: http://localhost:45743/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8

我了解到问题不在于我的$http请求或CORS。出现这个问题是因为我调用了一个异步函数,就好像它是同步的一样,而请求在有机会完成之前就被取消了。

下面是一个写得不好的代码示例。Logout函数封装$http请求。

authService.logout();
$window.location.href = location.origin;

下面是一个应该编写的代码示例。此代码按预期工作。

authService.logout().then(function success(data){
$window.location.href = location.origin;
}, function failure(data) {
$window.location.href = location.origin;
});

在不等待promise解析的情况下,会导致$http执行错误回调,但错误对象不可用。因此,当客户端提前取消POST时,我认为飞行前失败了。

最新更新