在Angular软件中执行API请求的正确方式,了解一下
全文共5358字,预计学习时长16分钟
来源:Pexels
本文将讨论如何在Angular应用程序中执行请求。
1. 使用拦截器来装饰请求
2. HttpClient 与HttpBackend的对比
3. 其他方式
这篇文章建立在我多年进行前端工作的经验(4年Angular工作经验)上。如有错误之处,请不吝赐教。
使用拦截器来装饰请求
使用API(应用程序接口)工作时, HTTP拦截器是一项主要特征。通过拦截,您使用拦截器,以检查HTTP请求并将其从应用程序发送到服务器,并从服务器返回应用程序的响应中进行转换。
简单来说:
在实际操作中,用户登录后,每个向后端传输的API都需要在标头添加授权,以核实用户的身份及授权。
例1:使用拦截器向请求添加JWT
[code]
[code]@Injectable() exportclass RequestInterceptorService implements HttpInterceptor{ constructor(private store: Store) { } intercept( request: HttpRequest<any>, next: HttpHandler ): Observable<any> { const userInfo = this.store.selectSnapshot<User>(state => state.AppState.user); const authReq = request.clone({ headers: new HttpHeaders({ 'Content-Type': 'application/json', 'Authorization': `Bearer ${userInfo.token}` }) }); return next.handle(authReq); } }
使用拦截器向请求添加jwt
例2: 使用拦截器控制应用程序上的微调器
[code]
[code]@Injectable({ providedIn: 'root' }) exportclass LoadingInterceptorService { activeRequests: number =0; constructor( private loadingScreenService: LoadingService ) { } intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { if (this.activeRequests===0) { this.loadingScreenService.startLoading(); } this.activeRequests++; return next.handle(request).pipe( finalize(() => { this.activeRequests--; if (this.activeRequests===0) { this.loadingScreenService.stopLoading(); } }) ) }; }
使用拦截器控制应用程序上的微调器
例 3: 使用拦截器来高速缓存请求
[code]
[code]@Injectable() exportclass CachingInterceptor implements HttpInterceptor { constructor(private cache: RequestCache) {} intercept(req: HttpRequest<any>, next: HttpHandler) { // continue if not cachable. if (!isCachable(req)) { return next.handle(req); } const cachedResponse = this.cache.get(req); return cachedResponse ? of(cachedResponse) : sendRequest(req, next, this.cache); } }
使用拦截器来高速缓存请求
也可以做更多与请求有关的事情:
· 在API失败的情况下显示模型。
· 响应后根据状态代码添加更多操作规则
· 覆盖URL请求或请求正文
拦截器将影响您的所有请求。那么,如何在Angular中自定义请求并禁用拦截器呢?下面来一起看看
HttpClient与HttpBackend的对比
我观察到很多开发人员仅在他们需要向后端发送请求时,才在Angular项目中使用HttpClient。而这是不正确的。
为什么?
来源:Pexels
因为我们由HttpClient发送的请求总是经过Angular的拦截器。为了解决这个问题,一些开发人员编写更多代码以禁用拦截器,我称之为“作弊代码”。而一些开发人员并不会使用拦截器来处理请求,并向每个请求添加标头。
这使代码充满代码异味和技术债务。开发人员必须使用上述两个选项之一来完成更多的工作。
解决办法: 使用 HttpClient 和HttpBackend 来发送请求。
唯一不同之处在于 HttpBackend 将请求直接发送到后端,而不经过拦截器链。
HttpService样本:
[code]
[code]import { Injectable } from'@angular/core'; import { HttpHeaders, HttpClient, HttpParams, HttpBackend } from'@angular/common/http'; import { Observable, throwError, of } from'rxjs'; import { catchError } from'rxjs/operators'; @Injectable({ providedIn: 'root' }) exportclass HttpService { privatehttpWithoutInterceptor: HttpClient; constructor( private http: HttpClient, private httpBackend: HttpBackend ) { this.httpWithoutInterceptor=new HttpClient(httpBackend); } privateformatErrors(error: any) { returnthrowError(error.error); } get(path: string, params: HttpParams =new HttpParams()): Observable<any> { return this.http.get(`${path}`, { params }) .pipe(catchError(this.formatErrors)); } put(path: string, body: Object = {}): Observable<any> { return this.http.put( `${path}`, JSON.stringify(body) ).pipe(catchError(this.formatErrors)); } post(path: string, body: Object = {}, options: Object = {}): Observable<any> { return this.http.post( `${path}`, JSON.stringify(body), options ).pipe(catchError(this.formatErrors)); } delete(path): Observable<any> { return this.http.delete( `${path}` ).pipe(catchError(this.formatErrors)); } _get(path: string, params: HttpParams =new HttpParams()): Observable<any> { return this.httpWithoutInterceptor.get(`${path}`, { params }) .pipe(catchError(this.formatErrors)); } _put(path: string, body: Object = {}): Observable<any> { return this.httpWithoutInterceptor.put( `${path}`, JSON.stringify(body) ).pipe(catchError(this.formatErrors)); } _post(path: string, body: Object = {}, options: Object = {}): Observable<any> { return this.httpWithoutInterceptor.post( `${path}`, JSON.stringify(body), options ).pipe(catchError(this.formatErrors)); } _delete(path): Observable<any> { return this.httpWithoutInterceptor.delete( `${path}` ).pipe(catchError(this.formatErrors)); } }
view rawhttp.service.ts hosted with ❤ by GitHub
使用httpclient和httpbackend的httpservice样本
您将做出决定,哪种方式经过拦截器,哪种方式不经过。
对于一些特定的API(应用程序接口)需要不同的标头或添加其他信息,才可以使用 HttpBackend来手动对其进行自定义。
其他方式
我以此作为标题是因为下面是一些您可能遇到过或没有遇到过的小用例。
失败后如何调用API?
[code]
[code]getConfig() { return this.http.get<Config>(this.configUrl) .pipe( retry(3), // retry a failed request up to 3 times ); }
重试失败的请求,最多三次
如果请求失败,使用retry()(异常重试)来延长尝试该请求的时间。
如何捕捉错误?
建议使用next()函数捕捉拦截器的错误。
[code]
[code]@Injectable() exportclass ErrorInterceptorService implements HttpInterceptor { constructor() { } intercept( request: HttpRequest<any>, next: HttpHandler ): Observable<any> { return next.handle(request).pipe( catchError(this.handleError) ); } privatehandleError(error: HttpErrorResponse) { if (error.errorinstanceof ErrorEvent) { console.error('An error occurred:', error.error.message); } else { console.error( `Backend returned code ${error.status}, `+ `body was: ${error.error}`); } returnthrowError( 'Something bad happened; please try again later.'); }; }
如何避免 XSRF攻击?
执行HTTP 请求时, 拦截器从cookie读取令牌,默认为XSRF-TOKEN,并将其设置为 HTTP 标头, X-XSRF-TOKEN。由于只有在您的域上运行的代码才能读取cookie,因此后端可以确定HTTP请求来自您的客户端应用程序而不是攻击者。
如果后端服务对XSRF令牌cookie或标头使用不同的名称,则使用HttpClientXsrfModule.withOptions() 来覆盖。
[code]
[code]imports: [ HttpClientModule, HttpClientXsrfModule.withOptions({ cookieName: 'My-Xsrf-Cookie', headerName: 'My-Xsrf-Header', }), ],
使用HttpClientXsrfModule 覆盖 XSRF令牌
来源:Pexels
本文包含了所有使用Angular应用程序的API时的必要信息,包括:
· 使用拦截器来管理请求和响应
· 如何使用HttpClient和HttpBackend
· 请求失败后,如何重新调回,如何捕捉错误和避免XSRF攻击。
希望此文章对您有帮助!
留言 点赞 关注
我们一起分享AI学习与发展的干货
欢迎关注全平台AI垂类自媒体 “读芯术”
(添加小编微信:dxsxbb,加入读者圈,一起讨论最新鲜的人工智能科技哦~)
- 点赞
- 收藏
- 分享
- 文章举报
- 分享一下SQL Server执行动态SQL的正确方式
- 在Linux 上安装 QQ 这种聊天软件的方式来了解一下
- 发一下微软 CRM 官方的 动态销售团队 转变组织执行销售工作 的方式.pdf
- 详解ASP.NET Core API 的Get和Post请求使用方式
- PHP:CURL分别以GET、POST方式请求HTTPS协议接口api
- 请求(Request)的参数(Parameter)里包含特殊字符(#等)的正确处理方式
- 【转】建立一个更高级别的查询 API:正确使用Django ORM 的方式
- EntityFramework Core进行读写分离最佳实践方式,了解一下(二)?
- 公司之前产品被抄了,损失惨重啊!想了解一下,当前有什么好的方式 能够做些防盗版方面保护吗?
- 发一下微软 CRM 官方的 动态销售团队 转变组织执行销售工作 的方式.pdf
- 我所了解的微信引流脚本软件的操作方法和原理,分享一下。
- Ajax 请求时莫明执行其它未调用的 Action 的原因及解决方式
- listview乱跳问题-listview乱跳问题:最后状态正确,就是执行动画过程有问题,点击某一个条目中的展开全文按钮,其它的条目也都会走一下动画展开一下,随后又恢复。但最后好、状态都是正确的。
- 建立一个更高级别的查询 API:正确使用Django ORM 的方式
- cmd中执行netsh wlan start hostednetwork 无法启动承载网络。 组或资源的状态不是执行请求操作的正确状态。
- Linux下使用java -jar运行可执行jar包的正确方式
- .net webservice 因 URL 意外地以“/GetAllArticle”结束,请求格式无法识别。 说明: 执行当前 Web 请求期间,出现未经处理的异常。请检查堆栈跟踪信息,以了解有关该
- 我想了解一下嵌入式软件开发
- angular和jquery的post请求方式
- Linux下使用java -jar运行可执行jar包的正确方式