提问者:小点点

角2 REST请求HTTP状态代码401更改为0


我正在开发Angular2应用程序。似乎当我的访问令牌过期时,401HTTP状态代码在响应对象中的值变为0。我正在接收401个未经授权的错误,但错误响应对象的状态为0。这会阻止我捕获401错误并尝试刷新令牌。是什么导致401 HTTP状态代码更改为0的HTTP状态代码?

这是火狐控制台的截图:

这是我的代码:

get(url: string, options?: RequestOptionsArgs): Observable<any> 
{
    //console.log('GET REQUEST...', url);

    return super.get(url, options)
        .catch((err: Response): any =>
        {
            console.log('************* ERROR Response', err);

            if (err.status === 400 || err.status === 422)
            {
                return Observable.throw(err);
            }
            //NOT AUTHENTICATED
            else if (err.status === 401)
            {                   
                this.authConfig.DeleteToken();
                return Observable.throw(err);
            }               
            else
            {
                // this.errorService.notifyError(err);
                // return Observable.empty();
                return Observable.throw(err);
            }
        })
        // .retryWhen(error => error.delay(500))
        // .timeout(2000, new Error('delay exceeded'))
        .finally(() =>
        {
            //console.log('After the request...');
        });
}

此代码驻留在自定义超文本传输协议服务中,该服务扩展了Angular2的HTTP,因此我可以在单个位置拦截错误。

在Google Chrome中,我收到以下错误消息:

无法加载XMLHttpRequesthttps://api.cloudcms.com/repositories/XXXXXXXXXXXXXXXX/branches/XXXXXXXXXXXXXXXX/nodesXXXXXXXXXXXXXXXX.请求的资源上不存在“Access Control Allow Origin”标头。起源'http://screwtopmedia.local.solutiaconsulting.com因此,不允许访问。响应的HTTP状态代码为401。

这很混乱,因为我在请求中包含了“访问-控制-允许-起源”标头。

以下是Google Chrome收到的结果图片:

我已经尝试访问“WWW-Authenticate”响应头作为捕获401的手段。但是,以下代码返回空值:

err.headers.get("WWW-Authenticate")

令人费解的是,我得到了一个CORS问题,因为当提供了有效的访问令牌时,我没有得到任何CORS错误。

如何捕获401 HTTP状态代码?为什么401 HTTP状态代码更改为0?

谢谢你的帮助。


共3个答案

匿名用户

此问题与CORS请求有关,请参阅此github问题

请求的资源上不存在“Access Control Allow Origin”标头

表示响应头中需要'Access-Control-Allow-Origin'

Angular没有获得任何状态代码,这就是为什么它会给您一个0,这是由于浏览器由于标题无效而不允许xml解析器解析响应

您需要将正确的CORS标题附加到错误响应以及成功

匿名用户

如果cloudcms.com在401响应中不设置访问-控制-允许-起源,那么您就无能为力了。你必须和他们一起打开支持票来确认这是否是正常的行为。

浏览器中的JavaScript(FF,Chrome

我创建了一个简单的测试,并得到与您相同的结果:

geturl() {
    console.log('geturl() clicked');
    let headers = new Headers({ 'Content-Type': 'application/xhtml+xml' });
    let options = new RequestOptions({ 'headers': headers });
    this.http.get(this.url)
        .catch((error): any => {
            console.log('************* ERROR Response', error);
            let errMsg = (error.message) ? error.message :
                error.status ? `${error.status} - ${error.statusText}` : 'Web Server error';
            return Observable.throw(error);
        })
        .subscribe(
        (i: Response) => { console.log(i); },
        (e: any) => { console.log(e); }
        );
}

在谷歌搜索了很多之后,我发现了以下内容(https://github.com/angular/angular.js/issues/3336):

lucassp于2013年8月19日发表评论

我发现这个问题有一段时间了,但是我忘记在这里发回复了。每个响应,甚至错误500,都必须附加CORS头。如果服务器没有将CORS头附加到错误500响应,那么XHR对象将不会解析它,因此XHR对象将没有任何响应主体、状态或任何其他响应数据。

Firefox网络监视器的结果似乎支持上述原因。

Javascript使用XHRHttpRequest进行http通信。

当XHR回复到达时,浏览器将处理标题,这就是您将看到401条网络消息的原因。但是,如果XHR回复来自不同的主机,则javascript和响应标头不包含CORS标头(例如访问控制允许来源:),浏览器将不会将任何信息传递回XHR层。因此,回复正文将完全为空,没有状态(0)。

我用FF 48.0进行了测试。1,铬52.0。2743.116和Safari 9.1。他们都有相同的行为。

使用浏览器网络监视器检查那些401未授权条目的响应头,很可能没有访问-控制-允许-起源头并导致您面临的问题。这可能是一个错误,也可能是服务提供商方面的设计。

Access Control Allow Origin是一个仅响应的http头。有关https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#The_HTTP_response_headers

匿名用户

我为云计算服务。我可以确认我们在API调用上正确设置了CORS头。但是,401响应的标题设置不正确。这一问题已经解决,修复程序将于本周末在公共API上发布。

顺便说一句,如果您使用我们的javascript驱动程序https://github.com/gitana/gitana-javascript-driver不再直接写入API,而是自动处理重新验证流,您根本不需要捕获401错误。

相关问题