node.js - 为 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
再次,如果我没有使用完美的术语,请原谅我,但我希望有人能理解我的意思。
解决方案
由于您在这种情况下处理的是静态图像而不是 Angular 组件,因此在服务器端逻辑而不是客户端实现重定向对我来说是有意义的,特别是因为客户端对图像的大多数网络请求都是通过img
元素及其src
属性自动处理。或者,如果您有多个需要从服务器获取图像的客户端怎么办?您不希望所有客户端都获得后备图像吗?也许不是......无论如何,我在下面描述了在客户端处理图像请求 404 的三种不同方法,以及使用 Node 和 Express 的一种服务器端方法。
简单的客户端方法
声明式版本
<img src="foo.jpg" onerror="if (this.src != 'fallback.jpg') this.src = 'fallback.jpg';">
我们使用原生元素onerror
内置的回调来检测 404,并将属性的值切换为备用图像的路径,以便浏览器自动处理图像的加载、解码和渲染。img
src
来源:输入默认图像以防 html <img> 的 src 属性无效?
命令式版本
您可以强制使用相同的方法。在包含所有图像的父组件中,使用ElementRef
Angular 提供的类来查询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.' });
}
});
希望这可以帮助!
推荐阅读
- directx-11 - 如何支持(在win7上)GDI、D3D11互操作?
- dpdk - Packet gen DPDK master lcore cannot be used for a port error
- javascript - 一次扫描多页
- c++ - 从基类实例化类对象(模板)
- html - CSS:社交图标显示的文本颜色与我设置的不同
- spring - 在 gradle 多项目中使用 kapt 和 spring-boot-configuration-processor
- html - 如何在 html 表格中插入一条水平线来分隔行
- reactjs - 设置增量数字输入的状态
- neo4j - Neo4j-enterprise 不允许删除
- java - 如何在 Android Studio 中做第二个 Webview