angular ssr 访问不存在的地址时响应 404 状态码
angular 启用 ssr 之后,访问一个不存在的地址时响应中的状态码也是 200,这可能会导致搜索引擎收录 404 页面,不利于 SEO。
解决这个问题要从 SSR 的原理开始,
node(express 服务) > angular 路由 > angular 对应的模块 > 有可能请求后端服务获取数据 > 渲染页面 -> 生成响应返回
那么解决办法其实很简单,就是当 angular 路由解析到这是一个 404 页面时,在生成响应的那步设置 response status code 为 404 即可。
- 在
server.ts
中传递request
和response
对象
app.get('*', (req, res) => {
res.render('index', { req, res }); /* 注入 (req,res)并传递给后面的管道 */
});
- 添加一个用于 404 的
component
,ng g c PageNotFound
在 angular 路由中设置页面所有未匹配到的地址到这个component
const routes: Routes = [
{ path: 'about', component: AboutComponent },
{ path: 'release', component: ReleaseComponent },
{ path: '', pathMatch: 'full', component: HomeComponent },
{ path: '**', component: PageNotFoundComponent } /* 用统配符 ** */
];
- 接下来在
page-not-found.component.ts
中设置Response
的状态码即可
import { Component, OnInit } from '@angular/core';
import { ServerResponseService } from '../services/server-response';
@Component({
selector: 'app-page-not-found',
templateUrl: './page-not-found.component.html',
styleUrls: ['./page-not-found.component.css'],
})
export class PageNotFoundComponent implements OnInit {
constructor(private svc: ServerResponseService) {
}
ngOnInit() {
this.svc.setNotFound(); /* 这里 ServerResponseService 是咱们手动封装的服务
}
}
ServiceResponseService.ts
import { RESPONSE } from '@nguniversal/express-engine/tokens';
import { Inject, Injectable, Optional } from '@angular/core';
@Injectable()
export class ServerResponseService {
constructor(
@Optional() @Inject(RESPONSE) private response: any /* 通过注入拿到前面第一步传进来的 Response */
) {
}
public setNotFound(message: string = 'not found') {
if (this.response) {
this.response.statusCode = 404;
this.response.statusMessage = message;
}
}
}
验证结果如下