Angular Universal 在渲染前不等待 api/http 请求

如何解决Angular Universal 在渲染前不等待 api/http 请求

我有一个全新的 angular 通用项目,它似乎伪装了所有的 HTML(这很好)。 但是,我正在尝试对我的 .NET 服务器进行 API 调用,该服务器是使用 weatherforecast API 构建的标准 API。

API 调用并且运行良好,但仅在我的 Web 应用程序从预渲染切换到 csr 后才会发生。见例一。

示例 1

enter image description here

如果我在页面上禁用了 javascript,这就是我得到的

enter image description here

这是HTML代码

  <div style="padding: 5rem">
    <h1>TEST</h1>
    <h2>{{ this.SampleMessage }}</h2>
    <div *ngFor="let product of weather$ | async">
      <p>{{ this.product.summary }}</p>
    </div>
  </div>

app.component.ts

import { AppService } from './app.service';
import { Component,OnInit } from '@angular/core';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-root',templateUrl: './app.component.html',styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
  title = 'ModernaMediaAngular';
  text:string = "test"

  weather$: Observable<any>;
  SampleMessage="Example of Angular Async Pipe";    
  
  constructor(private as: AppService,) {}

  async ngOnInit() {
    await this.getWeatherAsyncPipe();
    //non async
    this.as.getWeather().subscribe( res =>
      {
        this.text = res[0].date;
        console.log("got resolution");
        console.log(res);
        console.log(this.text);
      }
    );


  }
  public async getWeatherAsyncPipe() {    
        this.SampleMessage="Example of Angular Async Pipe";    
        this.weather$ = await this.as.getWeatherAsync();    
        console.log(this.weather$);
      }    
}

app.service.ts

import { environment } from './../environments/environment';
import { HttpClient,HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class AppService {
  public waeatherUrl = environment.url + '/api/weatherForecast/get'
  constructor(private http: HttpClient) { }

  getWeather() : Observable<object> {
    const headers = new HttpHeaders(
      {'Content-Type': 'application/json','Access-Control-Allow-Origin' : 'http://localhost:4200'
    }
      );
    var x = this.http.get(this.waeatherUrl,{headers: headers}).pipe();
    console.log(x);
    return x;
  }

  public getWeatherAsync():Observable<any> {
    return this.http.get<any[]>(this.waeatherUrl);    
  }
}

app.module.ts

import { BrowserStateInterceptor } from './interceptors/browserstate.interceptor';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http';

import { TransferHttpCacheModule } from '@nguniversal/common'

@NgModule({
  declarations: [
    AppComponent
  ],imports: [
    BrowserModule.withServerTransition({ appId: 'serverApp' }),TransferHttpCacheModule,AppRoutingModule,HttpClientModule,],bootstrap: [AppComponent]
})
export class AppModule {}

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 {}

ma​​in.ts

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

if (environment.production) {
  enableProdMode();
}

document.addEventListener('DOMContentLoaded',() => {
  platformBrowserDynamic().bootstrapModule(AppModule)
  .catch(err => console.error(err));
  console.log("DOMCONTENTLOADED");
});

每当预渲染尝试从 API 获取时,我也会收到我认为的 cors 错误。

chunk {main} main.js,main.js.map (main) 66.3 kB [initial] [rendered]
chunk {polyfills} polyfills.js,polyfills.js.map (polyfills) 141 kB [initial] [rendered]
chunk {runtime} runtime.js,runtime.js.map (runtime) 6.15 kB [entry] [rendered]
chunk {styles} styles.css,styles.css.map (styles) 118 bytes [initial] [rendered]
chunk {vendor} vendor.js,vendor.js.map (vendor) 2.8 MB [initial] [rendered]
Date: 2021-03-15T14:26:38.903Z - Hash: a20337e49cf8941fcbf6 - Time: 12492ms
Hash: af451acd21594faf190e
Time: 19059ms
Built at: 2021-03-15 15:26:41
      Asset      Size  Chunks                          Chunk Names
    main.js  6.44 MiB    main  [emitted]        [big]  main
main.js.map  6.99 MiB    main  [emitted] [dev]         main
Entrypoint main [big] = main.js main.js.map
chunk {main} main.js,main.js.map (main) 6.08 MiB [entry] [rendered]

Compiled successfully.
** Angular Universal Live Development Server is listening on http://localhost:4200,open your browser on http://localhost:4200 **
Observable {
  _isScalar: false,source: Observable {
    _isScalar: false,source: Observable {
      _isScalar: false,source: [Observable],operator: [MergeMapOperator]
    },operator: FilterOperator { predicate: [Function],thisArg: undefined }
  },operator: MapOperator { project: [Function],thisArg: undefined }
}

Observable {
  _isScalar: false,thisArg: undefined }
}

ERROR HttpErrorResponse {
  headers: HttpHeaders {
    normalizedNames: Map {},lazyUpdate: null,headers: Map {}
  },status: 0,statusText: 'Unknown Error',url: 'https://localhost:5001/api/weatherForecast/get',ok: false,name: 'HttpErrorResponse',message: 'Http failure response for https://localhost:5001/api/weatherForecast/get: 0 Unknown Error',error: ProgressEvent {
    type: 'error',target: XMLHttpRequest {
      onloadstart: null,onprogress: null,onabort: null,onerror: null,onload: null,ontimeout: null,onloadend: null,_listeners: [Object],onreadystatechange: null,_anonymous: undefined,readyState: 4,response: null,responseText: '',responseType: 'text',responseURL: '',statusText: '',timeout: 0,upload: [XMLHttpRequestUpload],_method: 'GET',_url: [Url],_sync: false,_headers: [Object],_loweredHeaders: [Object],_mimeOverride: null,_request: null,_response: null,_responseParts: null,_responseHeaders: null,_aborting: null,_error: null,_loadedBytes: 0,_totalBytes: 0,_lengthComputable: false
    },currentTarget: XMLHttpRequest {
      onloadstart: null,lengthComputable: false,loaded: 0,total: 0
  }
}

ERROR HttpErrorResponse {
  headers: HttpHeaders {
    normalizedNames: Map {},total: 0
  }
}

但控制台没有错误:

enter image description here

在我的 .NET 5 项目中的 startup.cs 中,我配置了 cors:

public void ConfigureServices(IServiceCollection services) {
    services.AddControllers();
    services.AddSwaggerGen(c => {
        c.SwaggerDoc("v1",new OpenApiInfo { Title = "ModernaMediaDotNet",Version = "v1" });
        });
    services.AddCors();
}

在公共无效配置(IApplicationBuilder app,IWebHostEnvironment env)

app.UseRouting();
app.UseCors(x => x
            .AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader()
            .SetIsOriginAllowed(origin => true) // allow any origin
            );

解决方法

我曾经在我们的测试环境中遇到过同样的问题,这是由于我们使用的是自签名证书,而哪个节点不喜欢。

我们最终在 server.ts 中添加了以下行,以便节点禁用 TLS 验证。

process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';

注意这是不安全的 (documentation),您不应在生产中使用它(您应该拥有有效证书)。

另一种选择是仅在服务器端进行 http 调用,您可以使用 HttpInterceptor

,

您的应用可能需要将 API 调用包装在区域宏任务中。

  1. npm install @bespunky/angular-zen
  2. 根据您的模块导入 RouterXModule.forRoot().forChild())。
  3. 让您的组件/服务扩展 RouteAware 类。
  4. 将您的 observable 封装在对 this.resolveInMacroTask() 的调用中。

您可以手动完成,但 RouteAware 会处理一切并且会给您带来额外的好处。

更多

Docs (See the Angular Universal section)

Live example using RouteAware

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res