我遇到了同样的错误。尝试从你的app.module
中移除TransferHttpCacheModule
,并创建自己的自定义http传输拦截器文件。
我创建了一个名为transfer-state.interceptor.ts
的文件,然后将其添加到app.module
providers:[]
中进行处理。下面的示例将展示如何连接它。我不确定这对你是否一定有效,但它确实让那个错误消失了。
import { BrowserModule, BrowserTransferStateModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule, HTTP_INTERCEPTORS } from "@angular/common/http";
import { AppRoutingModule } from './app-routing/app-routing.module';
import { AppComponent } from './app.component';
import { HomeComponent } from './modules/home/home.component';
import { SliderComponent } from './components/slider/slider.component';
import { WindowRefService } from './services/window-ref.service';
import { TransferStateInterceptor } from './interceptors/transfer-state.interceptor';
import { ServiceWorkerModule } from '@angular/service-worker';
import { environment } from '../environments/environment';
@NgModule({
declarations: [
AppComponent,
HomeComponent,
SliderComponent
],
imports: [
BrowserModule.withServerTransition({ appId: 'serverApp' }),
BrowserTransferStateModule,
AppRoutingModule,
HttpClientModule,
ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production })
],
providers: [
WindowRefService,
{
provide: HTTP_INTERCEPTORS,
useClass: TransferStateInterceptor,
multi: true
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
这是一种自定义传输状态文件的版本,但如果这个版本不起作用,有几种其他方法可以实现。
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';
import { Inject, Injectable, PLATFORM_ID } from '@angular/core';
import { Observable, of } from 'rxjs';
import { StateKey, TransferState, makeStateKey } from '@angular/platform-browser';
import { isPlatformBrowser, isPlatformServer } from '@angular/common';
import { tap } from 'rxjs/operators';
@Injectable()
export class TransferStateInterceptor implements HttpInterceptor {
constructor(
private transferState: TransferState,
@Inject(PLATFORM_ID) private platformId: any,
) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (request.method !== 'GET') {
return next.handle(request);
}
const stateKey: StateKey<string> = makeStateKey<string>(request.url);
if (isPlatformServer(this.platformId)) {
return next.handle(request).pipe(
tap((event: HttpResponse<any>) => {
this.transferState.set(stateKey, event.body);
})
);
}
if (isPlatformBrowser(this.platformId)) {
const transferStateResponse = this.transferState.get<any>(stateKey, null);
if (transferStateResponse) {
const response = new HttpResponse({ body: transferStateResponse, status: 200 });
this.transferState.remove(stateKey);
return of(response);
} else {
return next.handle(request);
}
}
}
}
如果您想要添加自定义缓存,可以通过安装 memory-cache
实现,但我还没有尝试过。这些文章对我很有帮助,也许它们也能帮到您。
https://itnext.io/angular-universal-caching-transferstate-96eaaa386198
https://willtaylor.blog/angular-universal-for-angular-developers/
https://bcodes.io/blog/post/angular-universal-relative-to-absolute-http-interceptor
如果您尚未添加,可能需要将 ServerTransferStateModule
添加到您的 app.server.module 文件中。
import { NgModule } from '@angular/core';
import {
ServerModule,
ServerTransferStateModule
} from "@angular/platform-server";
import { AppModule } from './app.module';
import { AppComponent } from './app.component';
@NgModule({
imports: [
AppModule,
ServerModule,
ServerTransferStateModule
],
bootstrap: [AppComponent],
})
export class AppServerModule {}
祝你好运!
(http://localhost:3000/api/...)
进行HTTP调用。但是在生产模式下,这会更改为相对URL(/api/...)
。我使用Angular环境变量实现了这一点。 - Benito