2016-12-30 57 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 

這是由提琴手捕獲的第二個請求。當我點擊Chrome瀏覽器

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 /燒瓶休息。當我看到這些請求是我看到的。那些說OPTIONS是空的請求,那些說POST是僅在Edge中發生的第二個並且是正確的。 enter image description here

+0

你在答覆中得到了什麼?頁面是否託管在相同的主機('http:// localhost:5000')?或者是另一個? (如果端口不同,則主機爲) –

+0

沒有主體的端口會返回空的200響應,包含登錄名和密碼的響應會返回我的JWT。 – Jhorra

+0

您是否可以在Chrome開發人員工具網絡選項卡中查看請求和響應? –

回答

1

它看起來像你有交叉原點請求的問題。
頁面主機(localhost:4200)與目標不同(localhost:5000)。

當發生這種情況鉻發出preflighted request

不同於簡單的請求(上面討論的),「預檢」請求第一 發送由OPTIONS方法的HTTP請求發送到資源上 其他域,在爲了確定實際請求是否安全 發送。跨站點請求以這種方式進行預檢,因爲它們可能會對用戶數據產生影響 。

你從那裏服務器獲得響應不包括需要CORS headers,併爲此鉻不發出實際POST請求。

+0

我相信你是對的。總是讓我感到簡單的事情。 – Jhorra

1

正如前面提到的Chrome發佈預衝的請求。 要繞過,您可以安裝this Chrome extension以啓用CORS並將*'Allow-Control-Allow-Origin:'添加到您的標題。這對localhost:8000上的django和localhost:4200上的angular2起作用。