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

Tom*_*eck 25 rest cors angular

我正在开发一个Angular2应用程序.似乎当我的访问令牌到期时,401 HTTP状态代码在Response对象中变为值0.我收到401 Unauthorized但ERROR Response对象的状态为0.这阻止我捕获401错误并尝试刷新令牌.是什么导致401 HTTP状态代码被更改为HTTP状态代码0?

这是Firefox控制台的截图:

在此输入图像描述

这是我的代码:

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...');
        });
}
Run Code Online (Sandbox Code Playgroud)

此代码驻留在一个自定义http服务中,该服务扩展了Angular2的HTTP,因此我可以在一个位置拦截错误.

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

XMLHttpRequest无法加载https://api.cloudcms.com/repositories/XXXXXXXXXXXXXXXX/branches/XXXXXXXXXXXXXXXX/nodesXXXXXXXXXXXXXXXX.请求的资源上不存在"Access-Control-Allow-Origin"标头.因此,不允许来源" http://screwtopmedia.local.solutiaconsulting.com "访问.响应具有HTTP状态代码401.

这很令人困惑,因为我在请求中包含'Access-Control-Allow-Origin'标头.

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

在此输入图像描述

我尝试访问'WWW-Authenticate'响应标头作为捕获401的方法.但是,以下代码返回NULL:

err.headers.get("WWW-Authenticate")
Run Code Online (Sandbox Code Playgroud)

令人费解的是,我遇到了CORS问题,因为在提供有效的访问令牌时我没有收到任何CORS错误.

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

谢谢你的帮助.

Ank*_*ngh 21

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

请求的资源上不存在"Access-Control-Allow-Origin"标头

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

Angular没有得到任何状态代码,这就是为什么它给你一个0由浏览器不允许xml parser解析response由于无效而导致的headers.

您需要正确的追加CORS标题error response以及success.


Joh*_*Siu 7

如果cloudcms.com没有设置Access-Control-Allow-Origin401响应,那么你无能为力.您必须与他们一起打开支持票证以确认这是否是正常行为.

浏览器中的javascript(FF,Chrome和Safari)如果发生CORS错误,我测试的将不会收到任何信息,而不是状态0. Angular2无法控制它.


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

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); }
        );
}
Run Code Online (Sandbox Code Playgroud)

经过大量的谷歌搜索后,我发现了以下内容(https://github.com/angular/angular.js/issues/3336):

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

我发现这个问题已经有一段时间但是我忘了在这里发布回复.每个响应,即使是错误500,也必须附加CORS标头.如果服务器没有将CORS头连接到Error 500响应,那么XHR对象将不会解析它,因此XHR对象内部将不会有任何响应主体,状态或任何其他响应数据.

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

Javascript请求将收到空响应. javascript请求

普通网址请求(复制并粘贴地址栏中的链接)将获得响应正文 普通网址请求

Javascript使用XHRHttpRequest进行http通信.

当XHR回复到达时,浏览器将处理标题,这就是您将看到这些401网络消息的原因.但是,如果XHR回复来自不同的主机,则javascript和响应头不包含CORS头(例如Access-Control-Allow-Origin: *),浏览器将不会将任何信息传递回XHR层.结果,回复正文将完全为空,没有状态(0).

我测试了FF 48.0.1,Chrome 52.0.2743.116和Safari 9.1.2,它们都具有相同的行为.

使用浏览器网络监视器检查这些401 Unauthorized条目的响应标头,很可能没有Access-Control-Allow-Origin标头并导致您遇到的问题.这可能是错误或服务提供商方面的设计.

Access-Control-Allow-Origin是仅响应http标头.有关https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#The_HTTP_response_headers的详细信息,参阅


小智 5

我为Cloud CMS工作.我可以确认我们在API调用上正确设置了CORS头.但是,对于401响应,标头未正确设置.这已经解决,本周末将在公共API上提供修复.

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