404 Not found page processing on Spartacus server-side rendering

Routing is handled by Routerlogic . Four different types of routes are evaluated:

  1. Routing should be handled by custom routing paths; clients add hardcoded routes and we should prioritize those.
  2. Routing is PLP (Product List Page) or PDP (Product Detail Page).
  3. Routing is a CMS (Content Management System) content page.
  4. The route is unknown (404 page not found).

It most likely falls into the third case when an incorrect URL is provided to Spartacus. Spartacus will use the CMS API to fetch the content page for a given URL. If the CMS cannot find a matching content page, it will return a 404 error. Spartacus will handle this 404 error and behind the scenes redirect the user to the CMS page not found.

Look at a concrete example:

We visit this url:

https://spartacus-demo.eastus.cloudapp.azure.com/electronics-spa/en/USD/OpenCatalogue/Cameras/Digital-Cameras/Digital-SLR/c/578n

In fact, it is to add one after category 578 n.

Then see this 404 not found page:

Spartacus tried to go to the CMS to find the CMS page 578nwith , but of course it couldn't find it. Then I looked for not-foundthe CMS page, and this time I found:

If this is the first visit, it will go to the SSR server and actually cause some unnecessary processing. This opens the door for attackers and adds unnecessary load on the SSR server.

As an optimization, on the SSR server we should immediately redirect to a (static) 404 page.

Someone on github proposed a solution :

Realize Rui's interceptor:

@Injectable()
export class NotFoundInterceptor implements HttpInterceptor {
    
    
  constructor(
    @Inject(PLATFORM_ID) private platformId: object,
    @Inject('response') private response: any,
  ) {
    
     }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    
    
    if (isPlatformServer(this.platformId)) {
    
    
      if (request.url.includes('/cms/pages')) {
    
    
        return next.handle(request).pipe(
          tap({
    
    
            next: event => {
    
    
              if (event instanceof HttpResponse && event.status === 404) {
    
    
                this.response.status(404);
              }
            },
            error: err => {
    
    
              if (err.status === 404) {
    
    
                this.response.status(404);
              }
            }
          })
        )
      }
    }

    return next.handle(request);
  }
}

Register this interceptor in the App module:

providers: [
   ...
    {
    
     provide: HTTP_INTERCEPTORS, useClass: NotFoundInterceptor, multi: true }
  ]

The code of server.ts:

server.get('*', (req, res) => {
    
    
    res.render(indexHtml, {
    
    
        req,
        providers: [
          {
    
     provide: APP_BASE_HREF, useValue: req.baseUrl },
          {
    
     provide: 'request', useValue: req },
          {
    
     provide: 'response', useValue: res }
        ],
      },
      (_error, html) => {
    
    
        if (res.get('X-Response-Status') === '404') {
    
    
          console.log(`[Node Express] 404 for url ${
      
      req.baseUrl}`);
          res.status(404).send(html);
        } else {
    
    
          // return rendered html for default
          res.send(html);
        }
      }
    );
  });

Guess you like

Origin blog.csdn.net/i042416/article/details/131221985