【发布时间】:2017-10-09 23:59:07
【问题描述】:
我有一个从 .NET Core 2 Angular 模板生成的 Angular v4 应用程序。
模板使用服务器端预渲染。
我正在尝试使用路由解析器在导航到显示图像表(或者更确切地说是图像记录)的页面之前获取数据。
每当我尝试使用解析器时,我都会从服务器端预渲染中获得 NodeInvocationException。
我是否需要在 HTTP 获取 URL 中提供完整路径(包括主机名)才能使其正常工作?
查看底部的更新以了解问题。
images.resolver.ts
import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { ImageModel } from './image.model';
import { ImagesService } from './images.service';
@Injectable()
export class ImagesResolver implements Resolve<ImageModel[]> {
constructor(private imagesService: ImagesService) { }
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> {
return this.imagesService.list();
}
}
images.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class ImagesService {
constructor(private httpClient: HttpClient) { }
list(): Observable<any> {
return this.httpClient.get(`api/images`);
}
get(id: number): Observable<any> {
return this.httpClient.get(`api/images/${id}`);
}
save(model: any): Observable<any> {
return this.httpClient.post(`api/images`, model);
}
update(model: any): Observable<any> | null {
return null;
}
delete(id: number): Observable<any> | null {
return null;
}
}
images-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { ImagesComponent } from './images.component';
import { ImageListComponent } from './image-list/image-list.component';
import { ImageComponent } from './image/image.component';
import { ImageResolver } from './shared/image.resolver';
import { ImagesResolver } from './shared/images.resolver';
const routes: Routes = [
{
path: '',
component: ImagesComponent,
children: [
{
path: '',
component: ImageListComponent,
resolve: {
images: ImagesResolver
}
},
{
path: ':id',
component: ImageComponent,
resolve: {
image: ImageResolver
}
}
]
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class ImagesRoutingModule { }
export const routedComponents = [
ImagesComponent,
ImageListComponent,
ImageComponent
];
更新
我已尝试在图像服务中附加 API 端点的基本 URL,但无济于事。我仍然遇到同样的错误。
constructor(
private httpClient: HttpClient,
@Inject('BASE_URL') private baseUrl: string
) { }
list(): Observable<any> {
return this.httpClient.get(`${this.baseUrl}api/images`);
}
经过一番挖掘,我在错误信息中发现了这个:
(未知 url)的 Http 失败响应:0 未知错误
我相信此消息来自 Angular 的 HttpClient,但我不知道为什么会收到此消息。
我尝试访问的完整端点是:
https://localhost:44317/api/images/featured
另一个更新
我发现禁用 SSL 后一切正常。我不想禁用此功能。
在服务器端预渲染时,如何配置 angular Universal / node / spa 服务以使用 SSL?
【问题讨论】:
-
将您的应用拆分为单独的项目可能会有所帮助。 .net core spa 模板看起来不错,但它们确实有其怪癖。一个是它输出无效的 html,这可能对 SEO 产生负面影响(在我看来,这是使用 ssr 的唯一原因)。要考虑的另一件事是,Angular 5 计划在我写这篇文章的几天/几周内发布。 V5 也应该对 SSR 有很多改进。我想我的意思是,对于单独的项目,更新 ng 并在它们出现时隔离这些错误非常容易。
-
你提出了一个很好的观点。老实说,我遇到问题的水疗中心部分用于内容管理,可以拆分为它自己的应用程序。然后我想它不需要考虑 seo,我可以使用 ssr 让客户端面向 seo 很重要的一面。
-
是的,这正是我的想法——你将 cms admin 作为一个成熟的 spa,然后使用常规 mvc 控制器来显示带有剃须刀页面的实际内容。所以 2 个单独的项目也会使从安全的角度来看,它更容易(mvc razor 呈现的所有内容都对任何人开放,并且 spa 的所有 api 控制器都具有授权属性)。将您的水疗中心细分为 admin.yoursite.com 之类的内容,内容将类似于 yoursite.com/content。只是一些想法。
-
或者(有 2 个独立的项目)您可以只为您的网站保留所有角度。执行此操作时,您可以选择要使用 ssr(使用通用)的页面。
标签: angular angular-ui-router server-side-rendering angular-universal asp-net-core-spa-services