我已经使用 Angular Universal 建立了一个 Angular 8 项目。为了防止重复的 HTTP 调用,Angular 提供了 TransferHttpCacheModule。
我按照官方文档将 TransferHttpCacheModule 添加到 Angular ( https://github.com/angular/universal/blob/master/docs/transfer-http.md )
我还尝试添加 BrowserTransferStateModule ( https://www.twilio.com/blog/faster-javascript-web-apps-angular-universal-transferstate-api-watchdog ),但这也不起作用。
app.module.ts
import {BrowserModule} from '@angular/platform-browser';
import {AppRoutingModule} from './app-routing.module';
import {AppComponent} from './app.component';
import {TransferHttpCacheModule} from "@nguniversal/common";
@NgModule({
declarations: [
AppComponent,
...
],
imports: [
BrowserModule.withServerTransition({appId: 'serverApp'}),
TransferHttpCacheModule, // <-
...
HttpClientModule
]
bootstrap: [AppComponent]
})
export class AppModule {
}
app.server.module.ts
import {NgModule} from '@angular/core';
import {ServerModule, ServerTransferStateModule} from '@angular/platform-server';
import {AppModule} from './app.module';
import {AppComponent} from './app.component';
import {ModuleMapLoaderModule} from '@nguniversal/module-map-ngfactory-loader';
@NgModule({
imports: [
AppModule,
ServerModule,
ModuleMapLoaderModule,
ServerTransferStateModule // <-
],
bootstrap: [AppComponent],
})
export class AppServerModule {
}
main.ts
document.addEventListener('DOMContentLoaded', () => {
platformBrowserDynamic()
.bootstrapModule(AppModule)
.catch(err => console.error(err));
});
我的 API 服务 api.service.ts
import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {Observable} from "rxjs";
@Injectable({
providedIn: 'root'
})
export class ApiService {
private API_URL = '/api/';
constructor(private http: HttpClient) {
}
public get<T>(url: string): Observable<T> {
return this.http.get<T>(this.API_URL + url);
}
public post<T>(url: string, payload: T): Observable<T> {
return this.http.post<T>(this.API_URL + url, payload);
}
...
}
HTTP 调用 home.component.ts
import {Component, OnInit} from '@angular/core';
import {ApiService} from "../../api.service";
import {Offer} from "../../offer-preview/offer.model";
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.sass']
})
export class HomeOffersComponent implements OnInit {
latestOffers: Offer[];
constructor(private apiService: ApiService) {
}
ngOnInit() {
this.apiService.get<Offer[]>("offer")
.subscribe(data => this.latestOffers = data);
}
}
根据官方 TransferHttpCacheModule 文档,浏览器不应向 /api/offer 生成 XHR,但我在 Developer Network Tools 中看到了 XHR 调用。
我做错了什么?我错过了什么吗?
最佳答案
这是因为 TransferHttpCacheModule
之间的绝对 URL 不匹配用作每个请求的缓存键。
例如:
只有当两个绝对 URL 相同时,请求才会被成功缓存。
为了避免这个缺点,您可以通过 BrowserTransferStateModule
实现自己的缓存。和拦截器,例如如所述here .
请务必只使用相对 URL:
const url = new URL(req.url);
const rel = url.toString().substring(url.origin.length);
this.transferState.set(makeStateKey(rel), event.body);
关于node.js - TransferHttpCacheModule 不会阻止 Angular 8 中的重复 HTTP 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57187758/