<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                # 對接后臺 本節我們嘗試完成個人中心后臺的對接。 ## 接口信息 我們為大家提供了如下接口來獲取當前登錄用戶的基本信息: ```bash GET /teacher/me ``` #### 參數 Parameters | type | name | Description | Schema | | ---------- | ------------------------------- | ------------ | ---------------- | | **Header** | **認證x-auth-token** *requried* | 獲取登錄信息 | 當前登錄教師實體 | #### 返回值 Responses | HTTP Code | Description | Schema | | --------- | ------------------------------------------------------ | ------ | | **200** | 認證x-auth-token合法 | Ok | | **401** | 未攜帶x-auth-token信息,未攜帶的x-auth-token信息不正確 | 未授權 | 接口中提到了x-auth-token信息,我們暫時先不考慮它,看看按以前請求思想會發生什么。 ## HttpClient ```typescript +++ b/first-app/src/app/personal-center/personal-center.component.ts @@ -1,5 +1,6 @@ import {Component, OnInit} from '@angular/core'; import {Teacher} from '../entity/teacher'; +import {HttpClient} from '@angular/common/http'; @Component({ selector: 'app-personal-center', @@ -9,18 +10,14 @@ import {Teacher} from '../entity/teacher'; export class PersonalCenterComponent implements OnInit { me = {} as Teacher; - constructor() { + constructor(private httpClient: HttpClient) { } ngOnInit(): void { - this.me = new Teacher( - 1, - 'zhangsan@yunzhi.club', - '張三', - 'password', - null as unknown as boolean, - 'zhangsan' - ); + const url = 'http://angular.api.codedemo.club:81/teacher/me'; + this.httpClient.get<Teacher>(url) + .subscribe(teacher => this.me = teacher, + error => console.log('請求發生錯誤', error)); } } ``` 單元測試中的動態測試模塊: ```typescript +++ b/first-app/src/app/personal-center/personal-center.component.spec.ts @@ -2,6 +2,7 @@ import {ComponentFixture, TestBed} from '@angular/core/testing'; import {PersonalCenterComponent} from './personal-center.component'; import {SexPipe} from './sex.pipe'; +import {HttpClientModule} from '@angular/common/http'; describe('PersonalCenterComponent', () => { let component: PersonalCenterComponent; @@ -9,7 +10,8 @@ describe('PersonalCenterComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [PersonalCenterComponent, SexPipe] + declarations: [PersonalCenterComponent, SexPipe], + imports: [HttpClientModule] }) .compileComponents(); }); @@ -20,7 +22,7 @@ describe('PersonalCenterComponent', () => { fixture.detectChanges(); }); - it('should create', () => { + fit('should create', () => { expect(component).toBeTruthy(); fixture.autoDetectChanges(); }); ``` 測試結果: ![image-20210308104228124](https://img.kancloud.cn/67/17/6717ade960183f748ad9d1bc5d2d68a8_2546x366.png) ## 登錄 與前面章節中對教師的操作不同,后臺獲取當前登錄教師的接口必須在**用戶登錄成功**后,才能夠獲取到。也就是說只有登錄的用戶才有資格訪問該接口。 那么如果在請求該接口前先完成用戶的登錄,是否可以請求成功呢?心動不如行動,我們參考登錄組件簡單寫下代碼: ```typescript +++ b/first-app/src/app/personal-center/personal-center.component.ts @@ -1,5 +1,6 @@ import {Component, OnInit} from '@angular/core'; import {Teacher} from '../entity/teacher'; +import {HttpClient, HttpHeaders} from '@angular/common/http'; @Component({ selector: 'app-personal-center', @@ -9,18 +10,29 @@ import {Teacher} from '../entity/teacher'; export class PersonalCenterComponent implements OnInit { me = {} as Teacher; - constructor() { + constructor(private httpClient: HttpClient) { } ngOnInit(): void { - this.me = new Teacher( - 1, - 'zhangsan@yunzhi.club', - '張三', - 'password', - null as unknown as boolean, - 'zhangsan' - ); - } + const authString = 'zhangsan:codedemo.club'; + const authToken = btoa(authString); + let httpHeaders = new HttpHeaders(); + httpHeaders = httpHeaders.append('Authorization', 'Basic ' + authToken); + this.httpClient + .get<Teacher>( + 'http://angular.api.codedemo.club:81/teacher/login', + {headers: httpHeaders}) + .subscribe(() => { + console.log('登錄成功,接著嘗試獲取當前登錄用戶'); + const url = 'http://angular.api.codedemo.club:81/teacher/me'; + this.httpClient.get<Teacher>(url) + .subscribe(teacher => { + console.log('請求當前登錄用戶成功'); + this.me = teacher; + }, + error => console.log('請求當前登錄用戶發生錯誤', error)); + }, + error => console.log('發生錯誤, 登錄失敗', error)); + } } ``` ![image-20210308105049039](https://img.kancloud.cn/a1/29/a12921dccbfb432925175c5f467f9fdc_1422x208.png) > 注意:此時的用戶名可能已經不是`zhangsan`,請參考登錄一節查看當前可用的用戶名。 可見:即使是在請求當前用戶前發起登錄請求,在登錄成功的情況下仍然沒有被后臺認為是**已認證用戶**。 ## 再學COOKIE 而值得一提的是:在前后臺統一的項目中,先完成用戶登錄再進行請求,是可以請求成功的。為什么會發生這種情況呢? 在前后臺地址相同的情況下,瀏覽器會自動處理用于認為的cookie信息。包括:將后臺返回的cookie信息緩存到瀏覽器中,以及再次請求中自動在header中攜帶當前已緩存的cookie信息。 比如我們在瀏覽器中直接訪問 [http://angular.api.codedemo.club:81](http://angular.api.codedemo.club:81),則會在請求頭中發現如下信息(如果沒有,就再次訪問一次): ![image-20210306145611485](https://img.kancloud.cn/e2/c0/e2c0d5cc50c206edce54639ac0b1e671_1850x840.png) 該信息則由瀏覽器自動處理。 但如果我們在當前項目中向樣的地址發起請求,則會發現請求頭中并沒有攜帶cookie信息,反而增加了Origin信息: ![image-20210306150116177](https://img.kancloud.cn/19/ec/19ecb19a274e7a7caaf454f5fa44e1ac_1904x828.png) 實際上,即使是我們使用類似于登錄時的代碼,手動的在header中添加cookie信息,瀏覽器在發起請求時也會將此信息刪除。 ```typescript +++ b/first-app/src/app/personal-center/personal-center.component.ts @@ -18,6 +18,7 @@ export class PersonalCenterComponent implements OnInit { const authToken = btoa(authString); let httpHeaders = new HttpHeaders(); httpHeaders = httpHeaders.append('Authorization', 'Basic ' + authToken); + httpHeaders = httpHeaders.append('Cookie', 'test cookie'); this.httpClient .get<Teacher>( ``` ![image-20210308110606538](https://img.kancloud.cn/15/54/1554e51e62a8726310d99dde0dd3fffe_1344x334.png) 這是瀏覽器出于保護普通的用戶,在安全方面做的考慮。 瀏覽器將這種在`http://localhost:4200`下請求`http://angular.api.codedemo.club:81`的請求稱為**跨域**請求。也就是說,瀏覽器將`http://localhost:4200`與`http://angular.api.codedemo.club:81`認為是兩個**域**。瀏覽器進行跨域判斷時,將對以下三個因素進行判斷: 1. 協議是否相同。比如在`http://www.codedemo.club`與`https://www.codedemo.club`的協議一個是`http`,一個是`https`,則認為協議不同。將被識別為跨域。 2. 域名是否相同。比如https://www.baidu.com與http://www.google.com,由于域名分別是`www.baidu.com`及`www.google.com`,所以認為域名不同。將被識別為跨域。 3. 端口號是否相同。瀏覽器發起請求時,會默認省略http協議的80端口,以及https協議的443端口。所以訪問:http://www.baidu.com,則相當于訪問:http://www.baidu.com:80;訪問https://www.baidu.com,則相當于訪問:https://www.baidu.com:443。除此以外,我們還可以為其指定特定的端口,比如我們的后臺地址為:`http://angular.api.codedemo.club:81`。該地址與`http://angular.api.codedemo.club`,一個端口為81,另一個為默認的80,不同。將被識別為跨域。 瀏覽器在發起請求時,如果發現請求的地址與當前訪問的地址在協議、域名以及端口號上有任意一點不同的時候,則將此次請求識別為跨域請求。 跨域更像是電影中的諜戰片,瀏覽器發現有人向外部傳遞信息時,自動的過濾掉被其認為是敏感信息的Cookie,以達到身份認證信息不被壞人獲取的目的(其實目的不是這樣的,但這不重要,只要知道Cookie是敏感信息,瀏覽器過濾掉了就可以)。 瀏覽器過濾掉了原來自動攜帶的用于認證的Cookie,這使得在跨域請求中,必須采取其的認證方式。 ## 域 什么是域呢?如果你對網絡知識感興趣,或是嘗試建立過個人站點,那么對它肯定不陌生。在建立個人站點時,重要的一環就是購買域名,比如`codedemo.club`就是一個域名。 域為domain的譯文,原意為`范圍、領土`,簡單來說就是用它來表示一定的范圍。在現實生活中,我們接觸了很多域。比如國家是一個域、省是一個域、市縣等都是一個域。有了域,我們就能快速的根據域來找現實生活中的事物通訊,比如由于河北工業大學座落天津市這個域,所以我們在與河北工業大學通訊時,可以先指定其域名**天津**,可見域就是指范圍。當前我們的現實世界里有個頂級的大域是宇宙,然后第二個域是地球,接下來的域有國家、省、市等。 在計算機的網絡世界里同樣也是如此,網絡里也有根域名、二級域名、三級域名: ![image-20210306151140032](https://img.kancloud.cn/50/c5/50c5536787d130115b5c121895661690_1442x514.png) 每個域名下都可以有很多臺計算機,每臺計算機在當前域下都有一個唯一的名字,我們把域名下計算機的名字稱作主機名。在進行http請求時,實際上是域中的某個計算機發起請求,所以在請求時要指名這個主機名。 ### 域名 知道了什么是域,域名就簡單了。這就像是張三是張三的名字,李四是李四的名字,河北工業大學是河北工業大學的名字一樣。為了區分不同的域,就需要對不同的域起名字。所以域名就是域的名字。 ## CORS 所以瀏覽器認為的跨域的請求,實際上是考慮了域、協議以及端口號。即使在同一個域下,如果協議或是端口號不同,也么被瀏覽器認為是跨域訪問。我們把域、協議以及端口號也稱為**同源**的三要素,即如果兩個請求的域、協議以及端口號均相同時,則認為兩個請求是同源的,而非同源則被認為是跨域的。所以,實際上**跨域**這個專有名詞是不確切、不足以正確的表達其中的含義的,正確的專有名詞應該是**跨源**,全稱為**跨源資源共享**,對應英文原文為:Cross-Origin Resource Sharing,稱寫為`CORS`。 而在前后臺分離的項目中,前臺與后臺的分離架構導致了前后臺必然不同源,而不同源時瀏覽器必然不攜帶cookie信息,也就無法實現**自動認證**。所以在CORS中,我們一般使用其它的認證方法。在下個小節中,我們將對其中的一種進行介紹。 | 名稱 | 地址 | | | ---------------------- | ------------------------------------------------------------ | ---- | | 跨域資源共享 CORS 詳解 | [https://www.ruanyifeng.com/blog/2016/04/cors.html](https://www.ruanyifeng.com/blog/2016/04/cors.html) | | | 跨源資源共享(CORS) | [https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS) | | | 域名 | [https://zh.wikipedia.org/wiki/%E5%9F%9F%E5%90%8D](https://zh.wikipedia.org/wiki/%E5%9F%9F%E5%90%8D) | | | 本節源碼 | [https://github.com/mengyunzhi/angular11-guild/archive/step4.3.zip](https://github.com/mengyunzhi/angular11-guild/archive/step4.3.zip) | |
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看