Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular http拦截器内的Angluar2路由_Angular_Typescript_Angular2 Routing - Fatal编程技术网

Angular http拦截器内的Angluar2路由

Angular http拦截器内的Angluar2路由,angular,typescript,angular2-routing,Angular,Typescript,Angular2 Routing,我使用角度2.4.8。通过REST与后端进行通信。在每个请求中,我需要在头中发送X-Auth-Token。令牌存储在会话上。当令牌过期时,服务器返回401状态。在这种情况下,我希望应用程序转到登录页面 我将http拦截器添加到我的项目中 @Injectable() export class HttpInterceptor extends Http { constructor(backend: XHRBackend , defaultOptions: RequestOpt

我使用角度2.4.8。通过REST与后端进行通信。在每个请求中,我需要在头中发送
X-Auth-Token
。令牌存储在会话上。当令牌过期时,服务器返回401状态。在这种情况下,我希望应用程序转到登录页面

我将http拦截器添加到我的项目中

@Injectable()
export class HttpInterceptor extends Http {

    constructor(backend: XHRBackend
        , defaultOptions: RequestOptions
        , private router: Router
    ) {
        super(backend, defaultOptions);
    }

    request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
        return super.request(url, options).catch((error: Response) => {
            if ((error.status === 401 || error.status === 403) && 
            (window.location.href.match(/\?/g) || []).length < 2) {
                // tslint:disable-next-line:no-console
                console.log('The authentication session expires.');
                window.sessionStorage.removeItem('auth-token');
                window.location.href = window.location.href + '/login';
                // this.router.navigate(['/login']);
                return Observable.empty();
            }
            return Observable.throw(error);
        });
    }
}
应用程序没有跟随链接。如何使路由器工作(导航)

编辑2018-01-22

我的
应用程序路由.module.ts

const routes: Routes = [
    {
        path: 'login',
        component: LoginComponent,
        resolve: {
            boolean: InitResolverService
        }
    },
    {
        path: '**',
        redirectTo: 'system'
    }
];

@NgModule({
    imports: [
        RouterModule.forRoot(
            routes
            // , { enableTracing: true } // <-- debugging purposes only
        )
    ],
    exports: [
        RouterModule
    ]
})
export class AppRoutingModule { }

在app.module.ts中,您应该添加:

{provide : Http, useFactory: (xhrBackend: XHRBackend, requestOptions: RequestOptions, router: Router) => new HttpInterceptor(xhrBackend, requestOptions, router),deps: [XHRBackend, RequestOptions, Router]}
在您的HttpInterceptor上:

 constructor(backend: ConnectionBackend, defaultOptions: RequestOptions, private _router: Router) {
    super(backend, defaultOptions);
  }

我并没有为此使用拦截器。对于每个API调用,我都使用
.catch
捕获错误并传递给此函数:

  // define the error handler in a separate method so we can reuse it 
  //in other methods
  private handleError(error: HttpErrorResponse | any) {
    console.error('ApiService::handleError', error);
    if (error.status === 401) {
      this.oAuthService.logOut();
    }
   return Observable.throw(error);
  }

希望这有帮助。

我们正在通过编写自己的定制http服务来解决这个问题,我们通过REST使用所有http请求

您还可以使用自定义http服务

  • 中央api路径
  • 使用令牌创建标头
  • 处理所有HTTP错误结果
简单代码示例

import { Injectable } from '@angular/core';
import { Http, Response, Headers } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import { ErrorObservable } from 'rxjs/observable/ErrorObservable';

export const API_PATH = "http://apipath"

@Injectable()
export class CustomHttpService {

    constructor(
        private http: Http,
        public router: Router) { }

    headerWithToken(): Headers {
        const headers = new Headers();
        headers.set('Authorization', 'bearer ' + localStorage.getItem('TOKEN'));
        headers.set('Content-Type', 'application/json');
        return headers;
    }

    get(params: URLSearchParams, method: string): Observable<any> {
        const url = `${API_PATH}/${method}`;
        return this.http.get(url, {params: params, headers: this.headerWithToken()})
        .map(
            res => <Array<any>>res.json()
        )
        .catch(err => {
            const result = this.handleErrors(err, this);
            return result;
        });
    }

    // put same way

    // post same way

    // delete same way

    public handleErrors(error: Response, obj: any): ErrorObservable {
        const errData = error.json();
        if (error.status === 401) {
            obj.router.navigate(['/login']);
        } else if (errData.message) {
            // give a message or something
        } else {
            console.log(errData);
        }
        return Observable.throw(error.json());
    }

}
从'@angular/core'导入{Injectable};
从'@angular/Http'导入{Http,Response,Headers};
从“rxjs/Observable”导入{Observable};
导入'rxjs/add/operator/map';
导入“rxjs/add/operator/catch”;
从“rxjs/observable/ErrorObservable”导入{ErrorObservable};
导出常量API_路径=”http://apipath"
@可注射()
导出类CustomHttpService{
建造师(
私有http:http,
公用路由器:路由器{}
headerWithToken():头{
常量头=新头();
headers.set('Authorization','bearer'+localStorage.getItem('TOKEN');
headers.set('Content-Type','application/json');
返回标题;
}
get(参数:URLSearchParams,方法:string):可观察{
常量url=`${API_PATH}/${method}`;
返回this.http.get(url,{params:params,headers:this.headerWithToken()})
.地图(
res=>res.json()
)
.catch(错误=>{
const result=this.handleErrors(err,this);
返回结果;
});
}
//同理
//同帖
//同样删除
公共句柄错误(错误:响应,对象:任何):可观察到的错误{
const errData=error.json();
如果(error.status==401){
obj.router.navigate(['/login']);
}else if(errData.message){
//发个信息什么的
}否则{
console.log(errData);
}
返回Observable.throw(error.json());
}
}

此代码适用于我:

@Injectable()
export class JwtInterceptor implements HttpInterceptor {

  constructor( public auth: AuthenticationService,
               private router: Router ) {
  } 

  public intercept( request: HttpRequest<any>, next: HttpHandler ): Observable<HttpEvent<any>> {
    let url: string = request.url;
    let method: string = request.method;
    console.log(`JwtInterceptor url=${url},   method=${method}`);

    return next.handle( request ).do( ( event: HttpEvent<any> ) => {
        console.log(`successful reply from the server for request=${request.urlWithParams}`);
    })
    .catch((responseError: any) => {

      // ResponseError Interceptor
      if (responseError instanceof HttpErrorResponse) {
        console.error('response in the catch: ', responseError);

          if ( responseError.status === 401 ) {
            let errorMsg: string = '';

            if ( responseError.statusText === 'Invalid credentials' ) {
              errorMsg = 'Username or password is incorrect';
            }

            // redirect to the login route
            this.router.navigate(['/login'], {queryParams: {msg: errorMsg}});
            return empty();
          }

        return throwError(responseError);
      }


      let error = new HttpErrorResponse({
        status: 500,
        statusText: 'Unknown Error',
        error: {
          message: 'Unknown Error'
        }
      });
      return throwError( error );

    }) as any;
  }
}
@Injectable()
导出类JwtInterceptor实现HttpInterceptor{
构造函数(公共身份验证:AuthenticationService,
专用路由器(路由器){
} 
公共截获(请求:HttpRequest,下一步:HttpHandler):可观察{
让url:string=request.url;
let方法:string=request.method;
log(`jwtinterceptorurl=${url},method=${method}`);
返回next.handle(request).do((事件:HttpEvent)=>{
log(`successful reply from server for request=${request.urlWithParams}`);
})
.catch((responseError:any)=>{
//响应者错误拦截器
if(HttpErrorResponse的responseError实例){
console.error('catch中的响应:',responseError);
if(responseError.status==401){
让errorMsg:string='';
if(responseError.statusText===“无效凭据”){
errorMsg='用户名或密码不正确';
}
//重定向到登录路径
this.router.navigate(['/login'],{queryParams:{msg:errorMsg}});
返回空();
}
回击投手(应答投手);
}
let error=新的HttpErrorResponse({
现状:500,
statusText:'未知错误',
错误:{
消息:“未知错误”
}
});
返回投掷器(错误);
})如有的话;
}
}

你确定你的路由器配置中有
/login
URL吗?当应用程序尝试重定向时,你能发布控制台错误吗?你能用它创建一个Plunk吗?@AlexParamonov是的。你能共享你的应用程序routng.module吗?现在我在编译过程中出错:静态解析符号值时遇到错误。不支持函数调用。考虑引用函数或lambda替换导出函数(在原.ts文件中的位置108:25),解析C/:App/SRC/APP/App.Mults模块中的符号AppMead模块。第108行是我放置
useFactory
make函数------导出函数httpFactory(后端:XHRBackend,选项:RequestOptions,路由器:router){返回新的HttpService(后端,选项,路由器);}--------并将此函数添加到提供者以解决问题--------{provide:HttpService,useFactory:httpFactory,deps:[xhrbakend,RequestOptions,Router]}这不是一个理想的解决方案,因为我在我的
ApiService
中使用它的每一个地方都必须重复这个逻辑,这与Tanser Chobanoğlu上面的回答类似。是的,你需要添加
.catch(This.handleError)
在每次api调用之后,但您可能无论如何都会这样做以捕获并抛出任何错误。拦截器也将是一个好方法,但它并不一定更好。
obj.router
来自何处?我已编辑了答案。我忘了添加路由器依赖项。
import { Injectable } from '@angular/core';
import { Http, Response, Headers } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import { ErrorObservable } from 'rxjs/observable/ErrorObservable';

export const API_PATH = "http://apipath"

@Injectable()
export class CustomHttpService {

    constructor(
        private http: Http,
        public router: Router) { }

    headerWithToken(): Headers {
        const headers = new Headers();
        headers.set('Authorization', 'bearer ' + localStorage.getItem('TOKEN'));
        headers.set('Content-Type', 'application/json');
        return headers;
    }

    get(params: URLSearchParams, method: string): Observable<any> {
        const url = `${API_PATH}/${method}`;
        return this.http.get(url, {params: params, headers: this.headerWithToken()})
        .map(
            res => <Array<any>>res.json()
        )
        .catch(err => {
            const result = this.handleErrors(err, this);
            return result;
        });
    }

    // put same way

    // post same way

    // delete same way

    public handleErrors(error: Response, obj: any): ErrorObservable {
        const errData = error.json();
        if (error.status === 401) {
            obj.router.navigate(['/login']);
        } else if (errData.message) {
            // give a message or something
        } else {
            console.log(errData);
        }
        return Observable.throw(error.json());
    }

}
@Injectable()
export class JwtInterceptor implements HttpInterceptor {

  constructor( public auth: AuthenticationService,
               private router: Router ) {
  } 

  public intercept( request: HttpRequest<any>, next: HttpHandler ): Observable<HttpEvent<any>> {
    let url: string = request.url;
    let method: string = request.method;
    console.log(`JwtInterceptor url=${url},   method=${method}`);

    return next.handle( request ).do( ( event: HttpEvent<any> ) => {
        console.log(`successful reply from the server for request=${request.urlWithParams}`);
    })
    .catch((responseError: any) => {

      // ResponseError Interceptor
      if (responseError instanceof HttpErrorResponse) {
        console.error('response in the catch: ', responseError);

          if ( responseError.status === 401 ) {
            let errorMsg: string = '';

            if ( responseError.statusText === 'Invalid credentials' ) {
              errorMsg = 'Username or password is incorrect';
            }

            // redirect to the login route
            this.router.navigate(['/login'], {queryParams: {msg: errorMsg}});
            return empty();
          }

        return throwError(responseError);
      }


      let error = new HttpErrorResponse({
        status: 500,
        statusText: 'Unknown Error',
        error: {
          message: 'Unknown Error'
        }
      });
      return throwError( error );

    }) as any;
  }
}