angular - 将数据从服务器端传递到客户端 Angular Universal

标签 angular angular-universal

有一种方法可以在服务器端执行期间定义常量值(例如缓存数据),并且也可以在客户端执行时使用?

它可以像缓存系统一样工作,即应用程序在服务器端运行时生成的缓存。

例如,我有一个由 api 资源 api/categories 返回的类别列表。我希望仅在服务器端运行时第一次调用我的应用程序时存储此请求的结果,并且此缓存数据可在客户端上使用,而无需再次请求api/categories。我怎样才能做到这一点?

我已经实现了 BrowserModule.withServerTransition 将状态从服务器传输到客户端,它可以工作,但真诚地我不明白它实际上是如何工作的。

那么..如何将任意数据从服务器端传递到 Angular 应用程序的客户端执行?

最佳答案

创建一个新的TransferHttpInterceptorService:

import {Injectable, Inject, PLATFORM_ID} from '@angular/core';
import {HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpResponse} from '@angular/common/http';
import {Observable, of} from 'rxjs';
import {tap} from 'rxjs/operators';
import {TransferState, makeStateKey, StateKey} from '@angular/platform-browser';
import {isPlatformServer} from '@angular/common';

@Injectable({
  providedIn: 'root'
})
export class TransferHttpInterceptorService implements HttpInterceptor {
  constructor(
    private transferState: TransferState,
    @Inject(PLATFORM_ID) private platformId: any) {
  }

  public intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    if (request.method !== 'GET') {
      return next.handle(request);
    }

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

    if (isPlatformServer(this.platformId)) {
      return next.handle(request).pipe(tap((event) => {
        this.transferState.set(key, (<HttpResponse<any>>event).body);
      }));
    } else {
      const storedResponse = this.transferState.get<any>(key, null);
      if (storedResponse) {
        const response = new HttpResponse({body: storedResponse, status: 200});
        this.transferState.remove(key);
        return of(response);
      } else {
        return next.handle(request);
      }
    }
  }
}

此处注意:如果您的服务器上使用了不同的主机或使用相对路径,则需要将 key 更改为

const key: StateKey<string> = makeStateKey<string>(request.url.split("/api").pop());

这可能不是最干净的解决方案,但它确实有效。

添加BrowserTransferStateModuleTransferHttpInterceptorService 从上面到 app.module.ts

imports: [
    BrowserModule.withServerTransition({appId: 'serverApp'}),
    BrowserTransferStateModule, <--
    ...
]
providers: [
{
  provide: HTTP_INTERCEPTORS,
  useClass: TransferHttpInterceptorService,
  multi: true
},
...
]

关于angular - 将数据从服务器端传递到客户端 Angular Universal,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57362329/

相关文章:

node.js - 无法在 ssr 中执行 https 请求

Angular/Rxjs 管道异步不适用于 ssr?

angular - 具有多种内容类型的 ContentChildren

angular - 如何从 Angular 4的文件上传输入中获取路径

authentication - "No provider for AuthGuard!"在 Angular 2 中使用 CanActivate

angular - Angular 万能锤的使用方法

javascript - localStorage 未定义 - 使用 Angular 通用,我有一个使用 localStorage 的函数

node.js - Angular 通用构建中断并出现以下错误 : throw Error ("not supported");

angular - mat-card-avatar 在初始页面加载时无法正确呈现

angular - Dragula 拖放复制 ng2 的一种方式