首页 > 解决方案 > 为 Angular 8 中的单个文件创建自定义 404 错误

问题描述

我似乎无法为此找到答案。

我可以使用我的 Routes 模块轻松地将所有用于页面路由的 404 路由到另一个路由,并使用它的派生。知道了。

{ path: '**', component: PageNotFoundComponent }

我有两个问题:

1)如何重定向到不需要成为我项目组件的静态文件?

2)如何为单个文件执行此操作?

如果我的术语不完全正确,请原谅我。我才刚刚开始使用 Angular。

基本上,我想要做的是将特定文件夹中图像的 404 错误重定向到同一文件夹中的已知图像。使用上面的例子,这个想法是这样的:

{ path: '/assets/custom-images/**', redirectTo: '/assets/custom-images/goodimage.png' }

在 .NET 中,我可以通过在“custom-images”文件夹中的 web.config 中添加一个简单的块来非常轻松地在 IIS 级别执行此操作,如下所示:

<httpErrors errorMode="Custom">
  <remove statusCode="404"/>
  <error statusCode="404" path="default.png" responseMode="Redirect"/>
</httpErrors>

这实际上工作得很好,当我将我的项目部署到我的 IIS 生产站点时,但是当我在我的 node.js 开发环境中工作时它不起作用,在端口:4200 上运行 ng serve

再次,如果我没有使用完美的术语,请原谅我,但我希望有人能理解我的意思。

标签: node.jsangularangular8

解决方案


由于您在这种情况下处理的是静态图像而不是 Angular 组件,因此在服务器端逻辑而不是客户端实现重定向对我来说是有意义的,特别是因为客户端对图像的大多数网络请求都是通过img元素及其src属性自动处理。或者,如果您有多个需要从服务器获取图像的客户端怎么办?您不希望所有客户端都获得后备图像吗?也许不是......无论如何,我在下面描述了在客户端处理图像请求 404 的三种不同方法,以及使用 Node 和 Express 的一种服务器端方法。

简单的客户端方法

声明式版本

<img src="foo.jpg" onerror="if (this.src != 'fallback.jpg') this.src = 'fallback.jpg';">

我们使用原生元素onerror内置的回调来检测 404,并将属性的值切换为备用图像的路径,以便浏览器自动处理图像的加载、解码和渲染。imgsrc

来源:输入默认图像以防 html <img> 的 src 属性无效?

命令式版本

您可以强制使用相同的方法。在包含所有图像的父组件中,使用ElementRefAngular 提供的类来查询img元素并设置它们的 onerror 回调。

import { Component, ElementRef } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {

  constructor(private elRef:ElementRef) {}
  ngAfterViewInit() {
    var imgs = this.elRef.nativeElement.querySelectorAll('img');
    imgs.forEach(img=>{
      img.onerror = switchToFallback;
    })
  }
}
function switchToFallback(){
  this.src = "https://cdn.shopify.com/s/files/1/0533/2089/files/placeholder-images-image_large.png?v=1530129081"
}

不必要的复杂 Angular 客户端方法

在这个方法中,我们创建了一个自定义图像组件来代替img模板中的原生元素。首先,您将在 Angular 代码中创建一个imagerequest.service.ts,以及一个my-custom-image组件。

图片请求服务将使用 AngularHttpClient尝试根据我们可以称之为组件imgScr属性的内容来获取图片my-custom-image。如果响应代码是 404,则图像请求服务将在将响应数据通过管道传输到 observable 之前请求并接收备用图像。(我假设您使用的是 RxJS)。

然后,在my-custom-image使用图像请求服务的组件内部,您将使用 Filereader API 从响应中创建一个 blob,您可以将其用作模板img呈现的实际元素中的 dataurl my-custom-image

使用 Node/Express 的服务器端方法

为了避免必须自己检查文件系统以查看图像是否存在,您可以使用express.static来提供图像文件。默认情况下,fallthrough选项express.static是 TRUE,这意味着如果没有静态文件匹配请求的路由,express 将执行下一个中间件函数。

在路由端点的末尾,添加一个中间件函数作为处理 404 的后备。所有其他路由端点不匹配的请求都将匹配这个请求。

// 404
app.use(function(req, res, next) {
  return res.status(404).send({ message: 'Route'+req.url+' Not found.' });
});

然后在您的 404 fallthrough 函数中,检查请求的路由,如果它与您的定义匹配,则重定向到后备图像。像这样的东西:

// 404
app.use(function(req, res, next) {
  if(req.path.includes("/assets/custom-images/")){
    res.redirect("/assets/custom-images/fallback.jpg");
  }else{
    return res.status(404).send({ message: 'Route'+req.url+' Not found.' });
  }
});

希望这可以帮助!


推荐阅读