在学习angular的过程中遇到的问题汇总记录
创建文件指令:
备注:name为创建的文件路径及名称,默认是在src/app下
创建module.ts文件:ng g m name
创建component.ts文件:ng g c name
创建name-routing.module.ts文件:ng g m --routing name
创建.service.ts文件:ng g service name
创建.interceptor.ts文件:ng g interceptor name
创建.guard.ts文件:ng g guard name
创建.pipe.ts文件:ng g pipe name
自定义运行端口:ng g --port 4201
备注:一个目录下有多个module.ts文件时,通过 ng g 在此目录下无法创建其它文件,因为系统不知道将文件引入哪一个module文件中
跨域请求解决
1.在根目录下创建文件proxy.config.json,里面的内容为:(其中url为接口地址)
{
“/api”: {
“target”: url,
“secure”: “false”,
“pathRewrite”: {"^/api": “”}
}
}
2.重新运行启动项目:ng serve --proxy-config proxy.config.json
获取Response Headers里面的token信息
很多时候需要登录校验才能获取到数据,我的是需要在登录的时候获取到Response Headers里面的authorization,后面调用接口需要将其传入请求头,处理方法如下:
在post请求时,添加 { observe: ‘response’ },我们打印_response的时候并不能看到有header里面的信息,但是使用headers.get(‘authorization’)方法能够获取到,打印下面的header能看到已经取到了authorization了,储存在localStorage里面,要用的时候取出来就行
login(username: string, password: string) {
return this.http.post("/api/user/login", {
username, password
}, { observe: ‘response’ }).pipe(map((_response: any) => {
const header = _response.headers.get(‘authorization’)
localStorage.setItem(‘authorization’, JSON.stringify(header))
console.log(header, “header”)
this.userSubject.next(_response.body);
return _response.body;
}))
}
调用接口需要传参数和设置请求头信息处理
通过HttpHeaders设置请求头参数,通过HttpParams设置get请求的参数
getData() {
const authorization = JSON.parse(localStorage.getItem('authorization'))
let headers = new HttpHeaders()
headers = headers.append('authorization', authorization)
let params = new HttpParams()
params = params.append('参数名1', "参数值1")
params = params.append('参数名2', "参数值2")
return this.http.get("/api/stat/analysis", { params, headers }).pipe(map(res=> {
return res
}))
}
未登录状态路由拦截
路由守卫,用户如果没有登录则自动跳转登录页面,否则跳转首页
1.创建LoginGuard路由守卫,我的是创建在app/core里面,运行 ng g guard core/login
2.写判断条件,我的判断条件是看authorization是否存在,存在则返回true,说明处于登录状态,否则就处于未登录状态,自动跳转到登录页面
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class LoginGuard implements CanActivate {
constructor(private router: Router) {}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): boolean {
return this.checkLogin();
}
checkLogin(): boolean {
const authorization = JSON.parse(localStorage.getItem('authorization'))
if (authorization) {
return true
} else {
this.router.navigate(['/passport/login']);
return false
}
}
}
3.在路由app-routing.module.ts里面引入LoginGuard
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { LoginGuard } from './core/login.guard';
import { LayoutComponent } from './layout/layout.component';
const routes: Routes = [
{
path: '', component: LayoutComponent, canActivate: [LoginGuard],
children: [
{ path: '', pathMatch: 'full', redirectTo: 'dashboard' },
{ path: 'dashboard', loadChildren: () => import('./pages/dashboard/dashboard.module').then((m) => m.DashboardModule) }
]
},
{ path: '', loadChildren: () => import('./pages/passport/passport.module').then((m) => m.PassportModule) },
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
统一设置请求头和统一处理请求错误
1.创建拦截器DefaultInterceptor,创建指令 ng g interceptor services/default (在services目录下自动生成default.interceptor.ts文件)
2.在app.module.ts中引入DefaultInterceptor,并注入providers中
const INTERCEPTOR_PROVIDES = [
{ provide: HTTP_INTERCEPTORS, useClass: DefaultInterceptor, multi: true }
]
providers: [{ provide: NZ_I18N, useValue: zh_CN }, …INTERCEPTOR_PROVIDES]
3.default.interceptor.t文件里的处理代码如下
import { Injectable } from '@angular/core';
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor,
HttpErrorResponse,
HttpResponse
} from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { catchError, mergeMap } from 'rxjs/internal/operators';
import { Router } from '@angular/router';
import { NzMessageService } from 'ng-zorro-antd';
@Injectable()
export class DefaultInterceptor implements HttpInterceptor {
constructor(
private router: Router,
private message: NzMessageService
) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const authorization = JSON.parse(localStorage.getItem('authorization'))
if (authorization) {
req = req.clone({
setHeaders: {
'authorization': authorization
}
})
}
let url = req.url;
const newReq = req.clone({ url });
return next.handle(newReq).pipe(
mergeMap((event: any) => {
if (event instanceof HttpResponse && event.status === 200)
return this.handleData(event)
return of(event)
}),
catchError((err: HttpErrorResponse) =>
this.handleData(err)
)
)
}
private handleData(ev: HttpResponse<any> | HttpErrorResponse): Observable<any> {
switch (ev.status) {
case 200:
if (ev instanceof HttpResponse) {
return of(ev)
}
break;
case 420:
if (ev instanceof HttpErrorResponse) {
this.message.error(ev.error.message);
}
localStorage.removeItem('authorization');
this.router.navigate(['/passport/login']);
break;
case 440:
if (ev instanceof HttpErrorResponse) {
this.message.error(ev.error.message);
}
localStorage.removeItem('authorization');
this.router.navigate(['/passport/login']);
break;
default:
if (ev instanceof HttpErrorResponse) {
this.message.error(ev.error.message);
}
break;
}
}
}