2016-12-30 1 views
3

Я понимаю, что мой заголовок немного расплывчатый, но вот моя ситуация. Я только что начал приложение, в котором я реализую JWT для аутентификации. У меня установлена ​​моя серверная группа, и я могу проверить, работает ли она по назначению.Странное поведение при отправке сообщения в Angular 2

Странность заключается в том, что при нажатии кнопки для входа в Chrome и Firefox он отправляет запрос один раз, без тела запроса. В Edge он отправляет его дважды, как только делает Chrome, а затем уже второй раз сразу после этого с неповрежденным телом.

У меня есть логин жестко закодирован прямо сейчас в почтовый запрос, чтобы попытаться устранить как можно больше вещей.

header.component.html

<ul id="links"> 
    <li> 
     <a href="/">Home</a> 
    </li> 
    <li> 
     <a href="/census">Census</a> 
    </li> 
    <li> 
     <button (click)="login()">Login</button> 
    </li> 
</ul> 

header.component.ts

import { Component, OnInit } from '@angular/core'; 
import { Router } from '@angular/router'; 

import { AuthenticationService } from '../_services/Authentication.Service'; 

@Component({ 
    selector: 'app-header', 
    templateUrl: './header.component.html', 
    styleUrls: ['./header.component.css'] 
}) 
export class HeaderComponent implements OnInit { 

    constructor(private _auth: AuthenticationService, private router: Router) { } 

    ngOnInit() { 
    } 

    login() { 
        this.loading = true; 
        this._auth.login(this.model.username, this.model.password) 
            .subscribe(result => { 

            }); 
    } 

} 

Authentication.Service.ts

import { Injectable } from '@angular/core'; 
import { Http, Headers, Response, RequestOptions } from '@angular/http'; 
import { Observable } from 'rxjs'; 
import 'rxjs/add/operator/map' 
  
@Injectable() 
export class AuthenticationService { 
    public token: string; 
  
    constructor(private http: Http) { 
        // set token if saved in local storage 
        var currentUser = JSON.parse(localStorage.getItem('currentUser')); 
        this.token = currentUser && currentUser.token; 
    } 
  
    login(usn: string, psw: string): Observable<boolean> { 
     let headers = new Headers({ 'Content-Type': 'application/json' }); 
     let options = new RequestOptions({ headers: headers }); 
     return this.http.post('http://localhost:5000/auth', JSON.stringify({ username: "email-removed", password: "password-removed" }), options) 
        .map((response: Response) => { return true; }); 
    } 
} 

Вот запрос для первого запроса я вижу из Chrome, ответ пустой

Request URL:http://localhost:5000/auth 
Request Method:OPTIONS 
Status Code:200 OK 
Remote Address:127.0.0.1:8888 
Response Headers 
view source 
Allow:POST, OPTIONS 
Content-Length:0 
Content-Type:text/html; charset=utf-8 
Date:Sat, 31 Dec 2016 00:08:05 GMT 
Server:Werkzeug/0.11.13 Python/3.5.2 
Request Headers 
view source 
Accept:*/* 
Accept-Encoding:gzip, deflate, sdch, br 
Accept-Language:en-US,en;q=0.8,es;q=0.6 
Access-Control-Request-Headers:content-type 
Access-Control-Request-Method:POST 
Host:localhost:5000 
Origin:http://localhost:4200 
Proxy-Connection:keep-alive 
Referer:http://localhost:4200/ 
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36 

Это второй запрос, снятый скрипачом. Это никогда не происходит, когда я нажимаю кнопку в хроме

POST http://localhost:5000/auth HTTP/1.1 
Accept: */* 
content-type: application/json 
Referer: http://localhost:4200/ 
Accept-Language: en-US,en;q=0.8,zh-Hans-CN;q=0.7,zh-Hans;q=0.5,es-US;q=0.3,es;q=0.2 
Origin: http://localhost:4200 
Accept-Encoding: gzip, deflate 
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393 
Content-Length: 58 
Host: localhost:5000 
Connection: Keep-Alive 
Pragma: no-cache 

{"username":"removed","password":"removed"} 

И ответ на второй

{ 
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0ODMxNDE5NDIsImlkZW50aXR5IjoiNTg2NmJiNDkwYzE3ZDdlMzk4MTk5MWNhIiwiZXhwIjoxNDgzMTQyMjQyLCJuYmYiOjE0ODMxNDE5NDJ9.VZGBYnPKPwyR0lWdG3kR8AecbLNlYCHMC1nimAHeP3w" 
} 

Вот еще одна странность/подсказкой для вас. Бэкэнд - это Python/Flask rest. Поскольку я смотрю, как поступают запросы, это то, что я вижу. Те, которые говорят OPTIONS, являются пустыми запросами, те, которые говорят POST, являются вторыми, которые происходят только в Edge и являются правильными. enter image description here

+0

Что вы получите в ответ? Является ли страница размещенной на одном и том же хостом ('http: // localhost: 5000')? Или другой? (если порт отличается от хоста) –

+0

Тот, у которого нет тела, возвращает пустой ответ 200, тот, в который вошли логин и пароль, возвращает мой JWT. – Jhorra

+0

Можете ли вы поделиться запросом и ответом, как показано на вкладке сети инструментов разработчика Chrome? –

ответ

1

Похоже, что у вас возникли проблемы с запросом на перекрестный поиск.
Хост страницы (localhost:4200) отличается от адресата (localhost:5000).

Когда это происходит хром выдает preflighted request:

В отличии от простых запросов (рассмотренных выше), «preflighted» запрашивает первый отправить запрос HTTP с помощью метода OPTIONS к ресурсу на другом домене, в чтобы определить, является ли фактический запрос безопасным. для отправки. Запросы межсайтовых запросов предваряются таким образом, поскольку они могут иметь последствия для пользовательских данных.

Ответ вы получите оттуда сервера не включает необходимость CORS headers, и для этого хром не выдает фактический POST запроса.

+0

Я считаю, что ты прав. Всегда простые вещи, которые меня достают. – Jhorra

1

Как уже упоминалось, вопросы, заданные в Chrome, предваряют предварительный запрос. Чтобы обойти это, вы можете установить this Chrome extension, чтобы включить CORS и добавить * 'Allow-Control-Allow-Origin: ' в заголовки.Это сработало для меня с django на localhost: 8000 и angular2 на localhost: 4200.

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