【问题标题】:Angular 9 SSR 404 Not Found Page with Status code带有状态码的 Angular 9 SSR 404 未找到页面
【发布时间】:2022-08-10 16:30:10
【问题描述】:

我正在使用带有 SSR 的 Angular 9,现在我正在尝试获取 404 页面。它与客户端成功合作。但状态总是以 200 OK 的形式出现。当我尝试使用 Angular ssr 时,它显示的 200 也是状态码。 我的 Angular 路由器已成功传递给 404 组件,但问题在于状态码。请各位朋友帮帮我...

我的路由器详细信息 -

{
path: \'404\',
loadChildren: () => import(\'./not-found/not-found.module\').then(m => m.NotFoundModule)
},
{
path: \'Home\',
loadChildren: () => import(\'./all-india/all-india.module\').then(m => m.AllIndiaModule)
},
{
path: \'**\',
loadChildren: () => import(\'./not-found/not-found.module\').then(m => m.NotFoundModule)
}

我的未找到组件.HTML

<h1>404 Not Found</h1>

我的未找到 Component.ts 文件

import { Component, OnInit, Optional, Inject,Injector, PLATFORM_ID } from \'@angular/core\';
import { RESPONSE } from \'@nguniversal/express-engine/tokens\';
import { isPlatformServer } from \'@angular/common\';
import { Response } from \'express\';

@Component({
selector: \'app-not-found\',
templateUrl: \'./not-found.component.html\',
styleUrls: [\'./not-found.component.css\']
})
export class NotFoundComponent implements OnInit {

constructor(
@Optional() @Inject(RESPONSE) private response: Response,@Inject(Injector) private injector: Injector,
@Inject(PLATFORM_ID) private platformId: Object) { }

ngOnInit() {
 if(isPlatformServer(this.platformId))//Only executes server side
     {
         const response = this.injector.get(RESPONSE) as Response;
         response.status(404);
     }
}
}

我的服务器.TS 文件

import \'zone.js/dist/zone-node\';

import { ngExpressEngine } from \'@nguniversal/express-engine\';
import * as express from \'express\';
import {REQUEST, RESPONSE} from \'@nguniversal/express-engine/tokens\';
import { join } from \'path\';

import { AppServerModule } from \'./src/main.server\';
import { existsSync } from \'fs\';

export function app() {
  const compression = require(\'compression\');
  const server = express();
  server.use(compression());
  const distFolder = join(process.cwd(), \'dist/angular-httpclient-example/browser\');
  const indexHtml = existsSync(join(distFolder, \'index.original.html\')) ? \'index.original.html\' : \'index\';

  // Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
  server.engine(\'html\', ngExpressEngine({
    bootstrap: AppServerModule,
  }));

  server.set(\'view engine\', \'html\');
  server.set(\'views\', distFolder);

server.get(\'*.*\', express.static(distFolder, {
    maxAge: \'1y\'
  }));

server.get(\'*\', (req, res) => {
    res.render(\'index\', {
      req: req,
      res: res,
      providers: [
          {
              provide: REQUEST, useValue: (req)
          },
          {
              provide: RESPONSE, useValue: (res)
          }
      ]
      });
  });

  return server;
}

function run() {
  const port = process.env.PORT || 4000;
  // Start up the Node server
  const server = app();
  server.listen(port, () => {
    console.log(`Node Express server listening on http://localhost:${port}`);
  });
}

// Webpack will replace \'require\' with \'__webpack_require__\'
// \'__non_webpack_require__\' is a proxy to Node \'require\'
// The below code is to ensure that the server is run only when not requiring the bundle.
declare const __non_webpack_require__: NodeRequire;
const mainModule = __non_webpack_require__.main;
const moduleFilename = mainModule && mainModule.filename || \'\';
if (moduleFilename === __filename || moduleFilename.includes(\'iisnode\')) {
  run();
}

export * from \'./src/main.server\';

我尝试了很多方法。状态代码没有任何作用。

  • Angular 应用程序是通过后端提供的(如 ASP.NET Core UseSpa 中间件),还是单独的应用程序?
  • @Pieterjan 嗨,感谢您的宝贵回复。我正在使用 PHP Codeigniter 的后端。通过服务通过其余 API 连接后端。
  • 导出类数据服务 { 私有 REST_API_SERVER = \'mybackendlink\'; public getlocationlist() { return this.httpClient.get(this.REST_API_SERVER + \'/get_location\') .pipe(retry(3), catchError(this.handleError)); } }
  • 如果您的 Angular 应用程序通过您的 api 提供服务,您只需在 spa 中间件之前添加一个中间件,评估请求 url,如果这与 Angular 应用程序中的 url 不匹配,则返回 404 状态码
  • 就像我在做here和here一样(中间件注入服务,调用这个方法)

标签: node.js angular express server-side-rendering angular-universal


【解决方案1】:

创建服务器端响应服务

@Injectable({
  providedIn: 'root'
})
export class ServerSideResponseService {
  private response: Response

  constructor(@Optional() @Inject(RESPONSE) response: any) {
    this.response = response
  }

  setNotFound(message = 'not found'): this {
    if (this.response) {
      this.response.statusCode = 404
      this.response.statusMessage = message
    }
    return this
  }
}

并在 Not Found Component 中使用它

@Component({
  selector: 'app-not-found',
  templateUrl: './not-found.component.html',
  styleUrls: ['./not-found.component.css']
})
export class NotFoundComponent implements OnInit {

  constructor(private ssr: ServerResponseService) {
    this.ssr.setNotFound();
  }
}

参考 https://github.com/DSpace/dspace-angular/commit/015b439a39208da4515eb4d18e4d21640fce1df0

【讨论】:

    猜你喜欢
    • 2019-03-10
    • 2011-11-21
    • 1970-01-01
    • 1970-01-01
    • 2020-10-30
    • 2018-11-28
    • 2014-07-29
    • 1970-01-01
    • 2011-08-01
    相关资源
    最近更新 更多