亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

理解Angular的providers給Http添加默認headers

2019-11-19 16:11:05
字體:
來源:轉載
供稿:網友

在一般的web應用里,經常會需要在每次發送Http請求的時候,添加header或者一些默認的參數。本文就來看看這個需求的幾種實現方式。通過這個實現,我們也能夠理解Angular的服務,及其providers的原理。

我們的目的是對于每個Http請求,都往Header里面添加一個token,用于在服務器端進行身份驗證。因為Http是一個服務,所以我就想當然的想到,我可以通過擴展框架提供的Http來添加。那么要怎么擴展一個框架提供的服務呢?那就是用providers。

NgModule里,有一個屬性providers,一般我們是用它來告訴框架,我們的app要用到我們定義的某些服務,例如我寫了一個UserService用來進行用戶數據的讀寫操作,又比如寫一個AuthGuardService來實現路由的Guard。對于框架或者使用的其他組件庫的服務,我們不需要在這里添加,只需要在imports里面加入相應的模塊即可。

自定義系統服務

那么,如果我們想修改框架提供的某個服務,例如想擴展它,該怎么實現呢?我們可以將擴展的這個服務,添加到providers里,只是添加的方式不太一樣。需要使用下面的方式:

@NgModule({ declarations: [  AppComponent ], imports: [  BrowserModule, RouterModule, HttpModule ], providers: [UserService, AuthGuardService,  { provide: Http, useClass: BaseHttp } ], bootstrap: [ AppComponent ]})

我們擴展了Http服務,新的服務的類名是BaseHttp,然后在providers里使用{ provide: Http, useClass: BaseHttp },告訴框架,我們要使用BaseHttp這個類,來提供對Http的實現。然后,在Angular的容器里面的Http服務實際上是BaseHttp這個類的實現,當我們通過注入獲得一個Http實例的時候,也是獲得的BaseHttp的實例。

實現自動添加Header

接下來,我們就來看看怎么實現自動的Header的添加。首先,我想到的第一種方式,就是擴展Http,在它的構造函數里設置一個默認的Header。

在構造函數中實現

@Injectable()export class BaseHttp extends Http { constructor (backend: XHRBackend, options: RequestOptions) {  super(backend, options);  let token = localStorage.getItem(AppConstants.tokenName);  options.headers.set(AppConstants.authHeaderName, token); }}

這個就是在構造函數里面,從localStorage里拿到token,然后放到RequestOptions里。看著似乎沒有問題,但是運行的時候發現,這個Http服務是在app初始化的時候創建的,所以這個構造函數在調用的時候,localStorage里可能還沒有token。這樣,即使用戶之后登陸了,之前的默認的options也不會更新。

在request中實現

所以,在構造函數中實現肯定是不行的,我通過觀察Http的接口(通過你使用的IDE,可以跟蹤到接口的定義文件,來查看接口的定義),看到有很多方法get(...), post(...), put(...)等,如果我需要重新實現所有的這些方法,那就太麻煩了,感覺沒有必要。然后,我看到request(...)方法,看他的方法的注釋知道,所有其他方法最終都會調用這個方法來發送實際的請求。所以,我們只需要重寫這個方法就可以:

@Injectable()export class BaseHttp extends Http { constructor (backend: XHRBackend, options: RequestOptions) {  super(backend, options) } request(url: string|Request, options?: RequestOptionsArgs): Observable<Response> {  const token = localStorage.getItem(AppConstants.tokenName)  if (typeof url === 'string') { // meaning we have to add the token to the options, not in url   if (!options) {    options = new RequestOptions({})   }   options.headers.set(AppConstants.authHeaderName, token)  } else {   url.headers.set(AppConstants.authHeaderName, token)  }  return super.request(url, options) }}

這個實現也很容易,唯一需要說明的是,這里的url它有可能有2種類型,string或Request,如果是string類型,說明這個url就是一個字符串,那么我們要設置的header肯定不會在它里面。

那如果url是Request類型呢?我們再來看看它的定義。通過看它的定義:

export declare class Request extends Body {  /**   * Http method with which to perform the request.   */  method: RequestMethod;  /**   * {@link Headers} instance   */  headers: Headers;  /** Url of the remote resource */  url: string;  /** Type of the request body **/  private contentType;  /** Enable use credentials */  withCredentials: boolean;  /** Buffer to store the response */  responseType: ResponseContentType;  constructor(requestOptions: RequestArgs);  /**   * Returns the content type enum based on header options.   */  detectContentType(): ContentType;  /**   * Returns the content type of request's body based on its type.   */  detectContentTypeFromBody(): ContentType;  /**   * Returns the request's body according to its type. If body is undefined, return   * null.   */  getBody(): any;}

我們知道它是一個類,里面有一個成員headers,然后我們再看看Headers這個類型,看到它有一個set()方法,是用來往headers里面添加值的,這正是我們需要的。

所以,在我們實現的BaseHttp.request()方法里,根據url的類型,再判斷options是否為空等。通過測試,這種方法能夠實現我們的需求,不管是初始化的時候在localStorage里面就有token,還是之后登陸,甚至退出后更新再登錄(會更新localStorage的token)等,都能滿足。

重新實現 RequestOptions

雖然上面的方法以及能夠解決問題,那么,能不能再簡單一點呢?因為我們需要的只是更新Options,但是,為了這個,我們攔截了Http的請求。那我們是不是可以直接擴展RequestOptions來實現呢?答案是yes。而且更容易,我們可以繼承BaseRequestOptions,重寫merge(...)方法。

@Injectable()export class AuthRequestOptions extends BaseRequestOptions { merge(options?: RequestOptionsArgs): RequestOptions {  let newOptions = super.merge(options);  let token = localStorage.getItem(AppConstants.tokenName);  newOptions.headers.set(AppConstants.authHeaderName, token);  return newOptions; }}

這個merge(...)方法會在每次請求的時候被調用,用來把請求的時候的options和默認options進行合并。

經過測試,這種方法也能夠完美的解決我們的需求。

總結

所以,這就是Angular強大與方便的地方,它使用了很多現象對象的特性,如繼承、接口、實現等;也用了很多服務器端Java框架的特性,例如容器等。上面說的provider也就是容器里面對象實例的提供者,本來RequestOptions類型的提供者是BaseRequestOptions,但是,我繼承了它,重寫了一個方法,把這個類型的提供者改成了我寫的類。這樣,Angular容器在初始化的時候,就會使用我提供的類來創建這個類型的實例。

而且,在這幾種實現方式的探索過程中,我完全沒有查看Angular的文檔,也沒有網上查什么資料。知識查看類或接口的定義,通過它的注釋,我就有了思路,然后嘗試實現,就成功了。這也是TypeScript給我嗎帶來的遍歷。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
青草青草久热精品视频在线网站| 成人国产在线视频| 中文字幕综合一区| 精品视频偷偷看在线观看| 国产精品自拍小视频| 亚洲自拍偷拍视频| 亚洲第一精品电影| 亚洲天堂av网| 亚洲美女性视频| 91精品久久久久久久久久久久久久| 91社区国产高清| 欧美性极品少妇精品网站| 91免费视频网站| 91在线观看免费高清| 精品中文视频在线| 亚洲福利在线看| 欧美一区第一页| 日本精品久久久久久久| 欧美日韩国产一区在线| 欧美日韩亚洲视频| 在线电影中文日韩| 欧美久久精品午夜青青大伊人| 成人做爰www免费看视频网站| 久久精品电影网| 人人爽久久涩噜噜噜网站| 久久香蕉国产线看观看av| 欧美老肥婆性猛交视频| 国产精品久久久久久久久粉嫩av| 国产精品视频午夜| 亚洲精品理论电影| 成人精品视频久久久久| 疯狂欧美牲乱大交777| 精品亚洲一区二区三区在线播放| 91丝袜美腿美女视频网站| 国产精品成人品| 国产精品va在线| 国产日韩欧美在线看| 高清日韩电视剧大全免费播放在线观看| 78m国产成人精品视频| 久久久免费av| 日韩有码在线播放| 亚洲国产福利在线| 精品国偷自产在线视频99| 日韩av电影在线免费播放| 亚洲一区二区在线| 社区色欧美激情 | 高清视频欧美一级| 亚洲无线码在线一区观看| 久久五月天综合| 青草青草久热精品视频在线网站| 粉嫩老牛aⅴ一区二区三区| 日av在线播放中文不卡| 久久噜噜噜精品国产亚洲综合| 一区二区三区 在线观看视| 色综合久久精品亚洲国产| 亚洲精品国产免费| 国产精品福利网| 中日韩美女免费视频网站在线观看| 一本大道久久加勒比香蕉| 欧美一区二区三区艳史| 国产视频久久久久久久| 日韩中文字幕在线播放| 日韩禁在线播放| 神马国产精品影院av| 久久精品视频免费播放| 国产在线不卡精品| 亚洲欧美日韩一区二区三区在线| 日韩在线观看网址| 欧美大片免费观看在线观看网站推荐| 18性欧美xxxⅹ性满足| 国产精品一区电影| 亚洲无限乱码一二三四麻| 亚洲xxxxx电影| 欧美性猛交xxxx乱大交3| 亚洲国产欧美一区二区三区久久| 伊人伊成久久人综合网站| 欧美精品制服第一页| 亚洲欧美另类中文字幕| 亚洲激情在线观看视频免费| 国产剧情久久久久久| 久久久久久久久久久av| 久久精品国产综合| 国产精品久久久久久久7电影| 97精品国产97久久久久久免费| 欧美性受xxxx黑人猛交| 亚洲女同精品视频| 日韩女优在线播放| 亚洲成人久久久| 亚洲美女视频网站| 欧美黑人视频一区| 久久久久久91| 精品福利在线视频| 亚洲欧洲成视频免费观看| 欧美日韩国产精品一区二区三区四区| 亚洲高清久久久久久| 日韩有码视频在线| 亚洲福利在线看| 亚洲欧美激情在线视频| 欧美亚洲国产精品| 国产精品视频中文字幕91| 欧美性猛交xxxx免费看漫画| 国产福利精品在线| 国产精品免费久久久| 91在线观看免费网站| 亚洲xxxx做受欧美| 亚洲国产精品小视频| 久久免费视频这里只有精品| 国产精品国模在线| 91精品国产综合久久香蕉922| 国产精品久久久久久久久久尿| 国产精品96久久久久久又黄又硬| 亚洲成人aaa| 精品久久久av| 成人羞羞国产免费| 精品日韩视频在线观看| 久久久亚洲影院| 日本19禁啪啪免费观看www| 国产精品91在线| 性色av一区二区三区免费| 伊人男人综合视频网| 欧美大片在线免费观看| 国外成人在线视频| 亚洲精品色婷婷福利天堂| 欧美日韩亚洲成人| 国产亚洲人成网站在线观看| 日韩美女中文字幕| 久久久久亚洲精品国产| 97视频在线观看免费| 欧美精品日韩三级| 日韩一区二区三区xxxx| 久久伊人91精品综合网站| 91免费看片网站| 日韩av在线看| 国产欧美亚洲视频| 国产精品色午夜在线观看| 韩国日本不卡在线| 亚洲欧美中文字幕在线一区| 亚洲国产日韩欧美在线动漫| 美女999久久久精品视频| 日韩视频中文字幕| 日韩视频免费中文字幕| 国产欧亚日韩视频| 亚洲精品美女免费| 丝袜美腿亚洲一区二区| 日韩经典第一页| 国产精品视频1区| 97香蕉久久超级碰碰高清版| 久久精品国产清自在天天线| 91国内在线视频| 国产精品高潮视频| 日本精品久久久久影院| 亚洲人午夜色婷婷| 久久久视频精品| 亚洲精品丝袜日韩| 日韩女优人人人人射在线视频| 国产精品va在线| 在线日韩欧美视频| 亚洲国产成人精品一区二区| 国产专区欧美专区| 岛国视频午夜一区免费在线观看| 欧美在线一级va免费观看| 欧美成aaa人片免费看| 视频在线一区二区| 日韩风俗一区 二区|