MIME类型验证器

2025年3月17日 | 阅读 7 分钟

在上一节中,我们成功地添加了图像控件来存储图像并预览给用户。一切都很好,但如果我们可以验证它以获得有效的图像,那就更好了。没有内置的验证器可以帮助我们实现这一点,所以我们将编写自己的验证器。我们将以以下方式在单独的文件中编写验证器

1) 我们将在 post-create 组件中创建一个新的 typescript 文件,并将其命名为 mime-type.validator.ts

Mime-Type Validator

MIME类型验证器的任务是获取控件的值,该值将是一个文件。之后,它使用文件阅读器再次读取该文件,然后将检查该文件的 MIME 类型。我们将一起编写此逻辑,因此它将是一个稍微复杂且高级的 JavaScript

2) 所有验证器都只是读取控件值并返回信息(是否有效)的函数。因此,我们将使用 export 关键字创建一个函数。为了更好地理解,我们将它命名为 mime-type。您可以为其赋予任何名称。


Mime-Type Validator

3) 现在,我们需要传递参数。我们将传递类型为 AbstractControl 的控件作为参数,如下所示


Mime-Type Validator

4) 我们还需要返回某些内容,这将是一个异步验证器,因为使用文件阅读器读取该文件是一个异步任务。一个普通的同步验证器只会返回一个 JavaScript 对象,在其中我们有一个带有我们自己的错误代码的键值对,然后是该错误代码的值,或者 null。如果验证器返回 null,则该值被视为有效,否则无效或失败。现在,对于异步验证器,它几乎相同,但是带有错误代码的 JavaScript 对象由一个 observable 或一个 promise 包装。因此,我们将返回一个 promise 或返回一个 observable。


Mime-Type Validator

5) promise 和 observable 都是泛型,这意味着它们最终将产生哪个值是清晰的。对于 promise,这将是该 JavaScript 对象,在这个对象中,我们有任何属性,并且我们不关心名称。我们只想说它应该有一个属性,并且我们这样做,用方括号,如下所示

[key: string] 意味着此返回类型将具有一个可以解释为字符串的属性,并且我们不关心名称。方括号不表示数组。它表示这是一个动态属性名称。

现在,该属性的值将是任何内容,因此,我们可以为该错误代码传递我们想要的任何值。


Mime-Type Validator

6) 我们用于 promise 的泛型类型与用于 observable 的泛型类型相同。这将是我们的函数定义,因此我们将收到一个错误,因为我们目前没有实现它。我们没有返回一个 promise 或一个 observable。


Mime-Type Validator

7) 在函数的正文中,我们将以以下方式提取文件


Mime-Type Validator

在上面的代码行中,我们将创建一个新的常量并存储控件的值。我们使用 **"as File"** 告诉 typescript 控件的值将是一个文件。

8) 我们将使用 FileReader,因此我们将创建一个 FileReader 的新对象,如下所示

现在,我们可以使用文件阅读器来读取该文件的值。以前,我们使用 **filereader.onload**,但我们现在需要 **onloadend**,这实际上不起作用,因为在这个函数中,我们需要返回一个 promise 或一个 observable,而 **filereader.onloadend** 既不是。这是一个同步代码,它只注册一个函数。

9) rxjs 给了我们一些东西,它允许我们将 **"filereader.onloadend = () =>{}"** 转换为一个 observable,也就是说,我们可以创建我们自己的 observable。为此,我们将为文件阅读器 observable 创建一个新常量,并通过调用 observable 创建我们自己的 observable,并且有一个静态 create() 方法。

使用 **create()** 方法,我们可以从头开始创建我们自己的 observable。

10) 现在,我们将一个函数作为参数传递给 observable。然后,这个函数会自动获得一个由 **rxjs** 传递的观察者,它的类型是观察者。


Mime-Type Validator

11) 我们在观察者中得到一个错误,因为它最终是一个泛型类型,并且类型将与我们的整个验证器最终将发出的 JavaScript 对象相同。


Mime-Type Validator

12) 在这个 observable 中,我们将获取我们的文件阅读器并向其添加 loadend 事件侦听器。还有一个函数,它将在 loadend 事件完成后执行。


Mime-Type Validator

13) 现在,我们有了 loadend 事件,在这里,我们希望使用这些信息发出一个新值,以了解这是一个有效文件还是无效文件。我们将在该事件侦听器内部执行此操作,因为存在额外的信息。在实现之前,我们将转到侦听器之后的行,在这里,我们将通过将文件读入数组缓冲区来开始该过程


Mime-Type Validator

它允许我们访问 MIME 类型。完成后,addEventListener loadend 将调用传递给事件侦听器的函数。

14) 现在,我们需要实现传递给事件侦听器的函数。我们将在那里执行 MIME 类型验证。我们将使用 Uint8Array 以以下方式创建一个新的 8 位无符号整数数组


Mime-Type Validator

在上面的代码中,我们使用 subarray(0, 4) 访问从 0 到 4 的子数组。这是让我们获取该 mine 类型的部分。

15) 现在,我们需要读取某种模式才能获得该文件类型,并且使用 **"for"** 读取该模式。在这个循环中,我们将遍历数组并从中提取一些信息。


Mime-Type Validator

16) 现在,要从中提取信息,我们将创建一个新变量 header,该变量最初将是一个空字符串,然后在 for 循环中,我们将附加到该字符串,这将是我们当前在循环中寻找的元素。


Mime-Type Validator

在上面的代码中,我们使用了 toString(16) 将数组元素转换为十六进制字符串。

17) 在获得十六进制字符串后,我们可以切换该标头,因为我们将拥有一个字符串,该字符串对不同的文件类型具有明确定义的模式。


Mime-Type Validator

在上面的代码中,每个案例都有一个代表特定文件类型(如 jpeg 和 png)的模式。

18) 我们有 isValid 变量,现在我们需要使用 Observer 来控制 observable。因此,我们将检查我们的 isValid 属性是否为真。如果为真,它将调用 Observer 的 next 函数来发出一个新值,该值将为 null,因为我们必须返回 null。如果不是真,我们发出一个不同的值,它是一个 JavaScript 对象,如下所示


Mime-Type Validator

19) 我们将调用 Observer 的 complete 函数来让任何订阅者知道我们已完成。


Mime-Type Validator

20) 我们需要做的唯一一件事是,我们需要通过简单地添加以下代码行来返回 observable


Mime-Type Validator

在添加这行代码后,我们将拥有一个有效的文件类型验证器。

21) 现在,我们将它与我们的表单关联起来,因此我们将返回到 post-create 组件。我们以以下方式导入 MIME 类型验证器


Mime-Type Validator

22) 我们将它添加到图像控件中,但不是作为验证器,而是作为异步验证器,如下所示


Mime-Type Validator

现在,我们正在以仅接受图像的方式初始化该图像。

23) 现在,我们将返回到我们的 post-create.component.html 文件,并确保如果获取了有效的图像预览值,我们不仅会显示预览,而且我们还希望检查图像验证,如下所示


Mime-Type Validator

我们保存所有文件,返回到我们的 angular 应用程序,并加载图像和视频。

Mime-Type Validator
Mime-Type Validator
Mime-Type Validator
Mime-Type Validator
Mime-Type Validator
Mime-Type Validator

因此,这里一切工作正常。在下一节中,我们将了解服务器端上传。

下载完整项目(Mime type validator.zip)