小編給大家分享一下Angular中providers如何給Http添加默認headers,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
讓客戶滿意是我們工作的目標,不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價值的長期合作伙伴,公司提供的服務(wù)項目有:域名申請、虛擬空間、營銷軟件、網(wǎng)站建設(shè)、績溪網(wǎng)站維護、網(wǎng)站推廣。
在一般的web應(yīng)用里,經(jīng)常會需要在每次發(fā)送Http請求的時候,添加header或者一些默認的參數(shù)。本文就來看看這個需求的幾種實現(xiàn)方式。通過這個實現(xiàn),我們也能夠理解Angular的服務(wù),及其providers的原理。
我們的目的是對于每個Http請求,都往Header里面添加一個token,用于在服務(wù)器端進行身份驗證。因為Http是一個服務(wù),所以我就想當然的想到,我可以通過擴展框架提供的Http
來添加。那么要怎么擴展一個框架提供的服務(wù)呢?那就是用providers。
在NgModule
里,有一個屬性providers
,一般我們是用它來告訴框架,我們的app要用到我們定義的某些服務(wù),例如我寫了一個UserService
用來進行用戶數(shù)據(jù)的讀寫操作,又比如寫一個AuthGuardService
來實現(xiàn)路由的Guard
。對于框架或者使用的其他組件庫的服務(wù),我們不需要在這里添加,只需要在imports
里面加入相應(yīng)的模塊即可。
自定義系統(tǒng)服務(wù)
那么,如果我們想修改框架提供的某個服務(wù),例如想擴展它,該怎么實現(xiàn)呢?我們可以將擴展的這個服務(wù),添加到providers
里,只是添加的方式不太一樣。需要使用下面的方式:
@NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, RouterModule, HttpModule ], providers: [UserService, AuthGuardService, { provide: Http, useClass: BaseHttp } ], bootstrap: [ AppComponent ] })
我們擴展了Http
服務(wù),新的服務(wù)的類名是BaseHttp
,然后在providers
里使用{ provide: Http, useClass: BaseHttp }
,告訴框架,我們要使用BaseHttp
這個類,來提供對Http
的實現(xiàn)。然后,在Angular的容器里面的Http服務(wù)實際上是BaseHttp
這個類的實現(xiàn),當我們通過注入獲得一個Http
實例的時候,也是獲得的BaseHttp
的實例。
實現(xiàn)自動添加Header
接下來,我們就來看看怎么實現(xiàn)自動的Header的添加。首先,我想到的第一種方式,就是擴展Http,在它的構(gòu)造函數(shù)里設(shè)置一個默認的Header。
在構(gòu)造函數(shù)中實現(xiàn)
@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); } }
這個就是在構(gòu)造函數(shù)里面,從localStorage里拿到token,然后放到RequestOptions里??粗坪鯖]有問題,但是運行的時候發(fā)現(xiàn),這個Http服務(wù)是在app初始化的時候創(chuàng)建的,所以這個構(gòu)造函數(shù)在調(diào)用的時候,localStorage里可能還沒有token。這樣,即使用戶之后登陸了,之前的默認的options也不會更新。
在request中實現(xiàn)
所以,在構(gòu)造函數(shù)中實現(xiàn)肯定是不行的,我通過觀察Http的接口(通過你使用的IDE,可以跟蹤到接口的定義文件,來查看接口的定義),看到有很多方法get(...), post(...), put(...)
等,如果我需要重新實現(xiàn)所有的這些方法,那就太麻煩了,感覺沒有必要。然后,我看到request(...)
方法,看他的方法的注釋知道,所有其他方法最終都會調(diào)用這個方法來發(fā)送實際的請求。所以,我們只需要重寫這個方法就可以:
@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) } }
這個實現(xiàn)也很容易,唯一需要說明的是,這里的url它有可能有2種類型,string或Request,如果是string類型,說明這個url就是一個字符串,那么我們要設(shè)置的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里面添加值的,這正是我們需要的。
所以,在我們實現(xiàn)的BaseHttp.request()
方法里,根據(jù)url的類型,再判斷options是否為空等。通過測試,這種方法能夠?qū)崿F(xiàn)我們的需求,不管是初始化的時候在localStorage里面就有token,還是之后登陸,甚至退出后更新再登錄(會更新localStorage的token)等,都能滿足。
重新實現(xiàn) RequestOptions
雖然上面的方法以及能夠解決問題,那么,能不能再簡單一點呢?因為我們需要的只是更新Options,但是,為了這個,我們攔截了Http的請求。那我們是不是可以直接擴展RequestOptions
來實現(xiàn)呢?答案是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(...)
方法會在每次請求的時候被調(diào)用,用來把請求的時候的options和默認options進行合并。
經(jīng)過測試,這種方法也能夠完美的解決我們的需求。
以上是“Angular中providers如何給Http添加默認headers”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學習更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
當前文章:Angular中providers如何給Http添加默認headers
分享鏈接:http://aaarwkj.com/article48/pcdeep.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動態(tài)網(wǎng)站、面包屑導(dǎo)航、網(wǎng)站營銷、ChatGPT、網(wǎng)頁設(shè)計公司、企業(yè)網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)