代码之家  ›  专栏  ›  技术社区  ›  Guerric P

使用相对URL时如何使用HTTP传输状态

  •  2
  • Guerric P  · 技术社区  · 6 年前

    我正在尝试实现内置的 TransferHttpCacheModule 以消除重复请求。我正在我的应用程序中使用此拦截器:

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        const authService = this.injector.get(AuthenticationService);
        const url = `${this.request ? this.request.protocol + '://' + this.request.get('host') : ''}${environment.baseBackendUrl}${req.url}`
    
        let headers = new HttpHeaders();
    
        if (this.request) {
          // Server side: forward the cookies
          const cookies = this.request.cookies;
          const cookiesArray = [];
          for (const name in cookies) {
            if (cookies.hasOwnProperty(name)) {
              cookiesArray.push(`${name}=${cookies[name]}`);
            }
          }
          headers = headers.append('Cookie', cookiesArray.join('; '));
        }
    
        headers = headers.append('Content-Type', 'application/json');
    
        const finalReq: HttpRequest<any> = req.clone({ url, headers });
        ...
    

    问题是 TransferHttpCacheModule

    有什么办法可以强迫他们离开吗 TransferHttpCacheInterceptor

    2 回复  |  直到 6 年前
        1
  •  6
  •   Poul Kruijt    6 年前

    您可以将拦截器放置在自己的模块中:

    @NgModule({
      providers: [
        { provide: HTTP_INTERCEPTORS, useClass: MyOwnInterceptor, multi: true }
      ]
    })
    export class MyOwnInterceptorModule {}
    

    TransferHttpCacheModule 在AppModule中:

    @NgModule({
      imports: [
        // ...
        TransferHttpCacheModule,
        MyOwnInterceptorModule
      ],
      // ...
    })
    export class AppModule {}
    

    这样,您的拦截器将在 TransferHttpCacheInterceptor . 但这感觉很奇怪,因为据我所知,导入是第一行的,然后是提供者。这样,您可以从导入中覆盖提供程序。你确定你不想换个方向吗?

        2
  •  1
  •   Harvix    6 年前

    我也遇到了同样的问题,通过在makeStateKey中删除主机解决了这个问题。

    你的 OwnHttpInterceptor

    你可以改变这个

    const key: StateKey<string> = makeStateKey<string>(request.url);
    

    对此

    const key: StateKey<string> = makeStateKey<string>(request.url.split("/api").pop());
    
        3
  •  0
  •   pkrawat1    6 年前

    我也有同样的问题,为角普遍支持在中国 angularspree

    =>创建一个 TransferStateService

    import { Inject, Injectable, PLATFORM_ID } from '@angular/core';
    import { TransferState, makeStateKey } from '@angular/platform-browser';
    import { isPlatformBrowser } from '@angular/common';
    
    /**
     * Keep caches (makeStateKey) into it in each `setCache` function call
     * @type {any[]}
     */
    const transferStateCache: String[] = [];
    
    @Injectable()
    export class TransferStateService {
      constructor(private transferState: TransferState,
        @Inject(PLATFORM_ID) private platformId: Object,
        // @Inject(APP_ID) private _appId: string
      ) {
      }
    
      /**
       * Set cache only when it's running on server
       * @param {string} key
       * @param data Data to store to cache
       */
      setCache(key: string, data: any) {
        if (!isPlatformBrowser(this.platformId)) {
          transferStateCache[key] = makeStateKey<any>(key);
          this.transferState.set(transferStateCache[key], data);
        }
      }
    
    
      /**
       * Returns stored cache only when it's running on browser
       * @param {string} key
       * @returns {any} cachedData
       */
      getCache(key: string): any {
        if (isPlatformBrowser(this.platformId)) {
          const cachedData: any = this.transferState['store'][key];
          /**
           * Delete the cache to request the data from network next time which is the
           * user's expected behavior
           */
          delete this.transferState['store'][key];
          return cachedData;
        }
      }
    }
    

    =>创建一个 TransferStateInterceptor 拦截服务器端平台上的请求。

    import { tap } from 'rxjs/operators';
    import { Observable, of } from 'rxjs';
    import { Injectable } from '@angular/core';
    import {
      HttpRequest,
      HttpHandler,
      HttpEvent,
      HttpInterceptor,
      HttpResponse
    } from '@angular/common/http';
    import { TransferStateService } from '../services/transfer-state.service';
    
    @Injectable()
    export class TransferStateInterceptor implements HttpInterceptor {
      constructor(private transferStateService: TransferStateService) {
      }
    
      intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        /**
         * Skip this interceptor if the request method isn't GET.
         */
        if (req.method !== 'GET') {
          return next.handle(req);
        }
    
        const cachedResponse = this.transferStateService.getCache(req.url);
        if (cachedResponse) {
          // A cached response exists which means server set it before. Serve it instead of forwarding
          // the request to the next handler.
          return of(new HttpResponse<any>({ body: cachedResponse }));
        }
    
        /**
         * No cached response exists. Go to the network, and cache
         * the response when it arrives.
         */
        return next.handle(req).pipe(
          tap(event => {
            if (event instanceof HttpResponse) {
              this.transferStateService.setCache(req.url, event.body);
            }
          })
        );
      }
    }
    

    module .

    providers: [
      {provide: HTTP_INTERCEPTORS, useClass: TransferStateInterceptor, multi: true},
      TransferStateService,
    ]
    
    推荐文章