2016-08-17 2 views
19

Я разрабатываю приложение Angular2. Кажется, что, когда мой токен доступа истекает, код статуса 401 HTTP изменяется в значение 0 в объекте Response. Я получаю 401 Unauthorized, но объект ответа ERROR имеет статус 0. Это мешает мне захватить ошибку 401 и попытаться обновить токен. Что вызывает изменение кода статуса HTTP 401 в код состояния HTTP 0?Angular2 Запрос REST Код статуса HTTP 401 изменяется на 0

Вот скриншот из консоли Фирефокса:

enter image description here

Вот мой код:

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...'); 
     }); 
} 

Этот код находится в таможенной службы HTTP, который простирается HTTP Angular2 так что я могу перехватить ошибки в одном место нахождения.

В 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:

enter image description here

Я попытался доступ заголовка «WWW-Authenticate» Response как средство ловушки для 401. Однако, следующий код возвращает NULL:

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

Это озадачивает, что я получаю вопрос CORS, потому что я не получаю никаких ошибок CORS при условии маркер доступа действителен.

Как заблокировать код статуса HTTP 401? Почему 401 код статуса HTTP изменяется на 0?

Благодарим за помощь.

+1

Если cloudcms.com не устанавливает контроль доступа-Разрешить-Происхождение в ответе 401, то вы ничего не можете сделать. Вам необходимо открыть билет поддержки с ними, чтобы убедиться, что это нормальное поведение. javascript в браузерах (FF, Chrome & Safari). Я тестировал, не получал никакой информации, если произошла ошибка CORS, отличная от состояния 0. Угловое2 не имеет никакого контроля над этим. –

+0

Вы решили проблему? Я имею в виду, что сервер не отправляет код с исправлениями, но на консоли хром вы видите 401, но угловой продолжает давать 0, как статус? – stackdave

ответ

5

Я работаю для Cloud CMS. Я могу подтвердить, что мы правильно настроили заголовки CORS для вызовов API. Однако для 401 ответов заголовки не устанавливаются должным образом. Это было решено, и исправление будет доступно в публичном API в конце этой недели.

BTW, если вы используете наш драйвер javascript https://github.com/gitana/gitana-javascript-driver вместо того, чтобы напрямую писать в API, тогда поток re-auth обрабатывается автоматически, и вам не нужно ломать ошибки 401.

2

Согласно W3C, если атрибут состояния установлен в 0, то это означает, что:

  • Государство UNSENT или ОТКРЫТ.

или

  • Флаг ошибки устанавливается.

Я думаю, что это не вопрос Angular2, похоже, что у вашего запроса возникли проблемы.

+0

интересный. Как вы это исправите? –

+0

запрос отправляется на URL REST, потому что я получаю код статуса 401. Я вижу 401 Несанкционированный результат. Но когда я дойду до предоставленного ответа, код состояния равен 0. Таким образом, состояние UNSENT не кажется правильным. –

1

У меня была такая же проблема, и из-за того, что сервер не отправил правильный ответ (даже если в журнале консоли указано значение 401, Угловая ошибка имела статус 0). Мой сервер был Tomcat с Java-приложением, используя Spring MVC и Spring Security.

Он теперь работает с использованием folowing установки:

SecurityConfig.java

... 
protected void configure(HttpSecurity http) throws Exception { 
.... 
    http.exceptionHandling() 
      .accessDeniedHandler(accessDeniedHandler) 
      .authenticationEntryPoint(authenticationEntryPoint); 
    // allow CORS option calls 
    http.authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll(); 
... 

SomeAuthenticationEntryPoint.java

@Component 
public class SomeAuthenticationEntryPoint implements AuthenticationEntryPoint { 

    @Override 
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { 
    HttpStatus responseStatus = HttpStatus.UNAUTHORIZED; 
    response.sendError(responseStatus.value(), responseStatus.getReasonPhrase()); 
    } 
} 

web.xml

<error-page> 
    <error-code>403</error-code> 
    <location>/errors/unauthorised</location> 
</error-page> 
<error-page> 
    <error-code>401</error-code> 
    <location>/errors/unauthorised</location> 
</error-page> 

контроллера в час andle в/ошибки/... определенные ранее

@RestController 
@RequestMapping("/errors") 
public class SecurityExceptionController { 

    @RequestMapping("forbidden") 
    public void resourceNotFound() throws Exception { 
     // Intentionally empty 
    } 

    @RequestMapping("unauthorised") 
    public void unAuthorised() throws Exception { 
     // Intentionally empty 
     } 

    } 
} 
+0

Благодарим вас за ответ. Услуга, которую я потребляю, - это сторонняя услуга. Таким образом, у меня нет контроля над/доступом к их серверу. Любая идея, почему я могу видеть код статуса 401 в консоли, но объект ошибки в Angular имеет код состояния 0? Это говорит о проблеме, которая является Угловой, а не сервером. –

2

Вы должны использовать монитор протокола 3-й участник HTTP (как CharlesProxy), а не Chrome Dev инструменты, чтобы подтвердить, какие заголовки фактически направляются на службу API и если он возвращается к 401.

+0

спасибо за ответ. Я также использую Postman и вижу 401 Несанкционированный статус, возвращенный из сторонних вызовов API при отправке истекшего токена. Поэтому я не считаю, что проблема связана с сторонним сервисом. Кажется, что статус ошибки объекта ответа об ошибке изменяется с 401 на 0 где-то внутри внутренних элементов Angular2. –

16

проблема связана с CORS просит см this github issue

Нет 'Access-Control-Allow-Origin' заголовок присутствует на запрошенный ресурс

означает, что в заголовках ответов требуется 'Access-Control-Allow-Origin'.

Угловые не получают какие-либо кодов состояния, поэтому он дает вам 0, которое вызывается браузер не позволяя xml parser разобрать response из-за недопустимый headers.

Необходимо добавить Заголовки CORS на ваш error response, а также success.

+1

, так что ответ от стороннего источника нуждается в «Access-Control-Allow-Origin» в заголовках тоже? Я добавил его с моей просьбой. –

+0

Этот код состояния по-прежнему странный, если честно, почему Google скажет, что это проблема запроса CORS, а не Firefox? –

+0

это не firefox, потому что я получаю ту же проблему в Google Chrome –

5

Если cloudcms.com делает, чтобы не установить Access-Control-Allow-Origin в ответе 401, то ничего вам не поделаешь. Вам необходимо открыть билет поддержки с ними, чтобы убедиться, что это нормальное поведение.

javascript в браузерах (FF, Chrome & Safari) Я тестировал, не получал никакой информации, если произошла ошибка CORS, отличная от состояния 0. Угловое2 не имеет никакого контроля над этим.


Я создал простой тест и получить тот же результат, как ваша:

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); } 
     ); 
} 

После долгих Googling, я обнаружил следующее (https://github.com/angular/angular.js/issues/3336):

lucassp прокомментировал 19 августа , 2013

Я нашел проблему некоторое время, но я забыл сообщение здесь, ответ. КАЖДЫЙ ответ, даже Ошибка 500, должен иметь прикрепленные заголовки CORS. Если сервер не прикрепляет заголовки CORS к ответу «Ошибка 500», объект XHR не будет анализировать его, поэтому объект XHR не будет иметь никакого тела ответа, статуса или любых других данных ответа внутри.

Результат от сетевого монитора Firefox, похоже, поддерживает указанную выше причину.

Javascript-запрос получит пустой ответ. javascript request

Plain URL запроса (копия & вставить ссылку в адресной строке) получит тело ответа Plain url request

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

Смежные вопросы