ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ng-zorro-antd Upload 上传前转换文件:借助 nzBeforeUpload 在请求发出前为文件添加水印

ng-zorro-antd Upload 上传前转换文件:借助 nzBeforeUpload 在请求发出前为文件添加水印 UI组件前端【免费下载链接】ng-zorro-antdAngular UI Component Library based on Ant Design项目地址https://gitcode.com/gh_mirrors/ng/ng-zorro-antd点击查看免费下载在 ng-zorro-antd 的nz-upload组件中nzBeforeUpload是连接用户选中文件与文件真正上传到服务器之间的关键钩子它不只用于校验拦截还能在请求发出之前改写文件内容本身。本指南以官方演示transform-file为骨架完整讲解如何用nzBeforeUpload结合 FileReader、Canvas 与 RxJS Observable 在浏览器端为图片添加水印并深入源码剖析其底层调用链、返回值类型与 uid 复用机制帮助你在此基础上实现图片压缩、格式校验、异步审核等各类上传前处理需求。一、问题背景为什么需要上传前转换在很多业务场景中用户选中的文件并不能直接上传到服务器图片需要加水印版权、来源标识原图过大需要压缩、缩放后再上传以节省带宽与存储上传前需要异步校验如请求服务端检查文件合法性需要把文件改写为另一种格式如截图转 Blob。nzBeforeUpload正好为这些需求提供了一个统一入口。官方演示transform-file见 components/upload/demo/transform-file.ts的说明非常凝练使用nzBeforeUpload在请求之前转换文件例如添加水印。它展示了一条完整的读文件 → 画布绘制水印 → 转 Blob → 交还上传组件的流水线。二、先看完整示例Canvas 加水印的官方实现演示组件的模板与处理函数完整代码如下取自 components/upload/demo/transform-file.tsimport { Component } from angular/core; import { Observable } from rxjs; import { NzButtonModule } from ng-zorro-antd/button; import { NzSafeAny } from ng-zorro-antd/core/types; import { NzIconModule } from ng-zorro-antd/icon; import { NzUploadFile, NzUploadModule } from ng-zorro-antd/upload; Component({ selector: nz-demo-upload-transform-file, imports: [NzButtonModule, NzIconModule, NzUploadModule], template: nz-upload nzActionhttps://www.mocky.io/v2/5cc8019d300000980a055e76 [nzBeforeUpload]transformFile button nz-button nz-icon nzTypeupload / Upload /button /nz-upload }) export class NzDemoUploadTransformFileComponent { transformFile (file: NzUploadFile): ObservableBlob new Observable(observer { const reader new FileReader(); reader.readAsDataURL(file as NzSafeAny); reader.onload () { const canvas document.createElement(canvas); const img document.createElement(img); img.src reader.result as string; img.onload () { const ctx canvas.getContext(2d)!; ctx.drawImage(img, 0, 0); ctx.fillStyle red; ctx.textBaseline middle; ctx.fillText(Ant Design, 20, 20); canvas.toBlob(blob { observer.next(blob!); observer.complete(); }); }; }; }); }要点提炼模板侧nz-upload上通过[nzBeforeUpload]transformFile绑定处理函数nzAction指定上传地址示例为演示用的 mock 接口。处理函数签名接收NzUploadFile返回ObservableBlob——即把转换后的文件以异步流的形式交还上传组件。必须使用箭头函数定义官方 API 文档components/upload/doc/index.zh-CN.md明确要求nzBeforeUpload务必使用定义处理方法以保证this指向组件实例。三、逐段拆解本地图片转换的完整流程transformFile内部是一条标准的浏览器端图片处理管线共五步1. 用 FileReader 把文件读为 Data URLconst reader new FileReader(); reader.readAsDataURL(file as NzSafeAny);FileReader.readAsDataURL将选中的图片文件异步读取为 base64 形式的 Data URL。此时file虽是NzUploadFile类型但底层就是浏览器File对象因此可直接传入。由于读取是异步的后续逻辑都挂在reader.onload回调里。2. 创建画布与图片对象const canvas document.createElement(canvas); const img document.createElement(img); img.src reader.result as string;用读取结果作为img的src并创建一块画布。canvas的尺寸默认与绘制内容一致这里未显式设置宽高drawImage会以图片原始尺寸绘制。3. 在画布上绘制原图与水印img.onload () { const ctx canvas.getContext(2d)!; ctx.drawImage(img, 0, 0); ctx.fillStyle red; ctx.textBaseline middle; ctx.fillText(Ant Design, 20, 20); ... };img.onload确保图片解码完成后才开始绘制。drawImage(img, 0, 0)先把原图完整画上随后用fillStyle设置水印颜色示例为红色、textBaseline middle设置文本基线再通过fillText在坐标 (20, 20) 处写入 Ant Design 文本水印。4. 导出为 Blobcanvas.toBlob(blob { observer.next(blob!); observer.complete(); });canvas.toBlob把画布内容异步导出为Blob对象默认 PNG 格式。得到结果后通过observer.next(blob)把转换后的文件发射出去并observer.complete()结束 Observable 流。5. 用 Observable 包装整个异步过程外层new Observable(observer { ... })把读取文件 → 解码图片 → 绘制水印 → 导出 Blob这一串浏览器异步回调统一收敛为单一的可订阅流正好与nzBeforeUpload支持的Observable返回值对接。四、源码级原理nzBeforeUpload 在内部如何被消费了解调用链能让你清楚返回 Blob与返回 true究竟有什么区别。1. 输入定义在 components/upload/upload.component.ts 中钩子被声明为Input() nzBeforeUpload?: (file: NzUploadFile, fileList: NzUploadFile[]) NzBeforeUploadFileType;而返回类型定义在 components/upload/interface.tsexport type NzBeforeUploadFileType | boolean | Observableboolean | NzUploadFile | Blob | File | boolean | Promiseboolean | NzUploadFile | Blob | File | boolean;即返回值可以是同步布尔值也可以是Observable或Promise异步流中的值可以是boolean、NzUploadFile、Blob或File。2. 消费逻辑upload-btn.component.tsnzUpload组件会把nzBeforeUpload打包进ZipButtonOptions见 components/upload/upload.component.ts最终由按钮组件 components/upload/upload-btn.component.ts 的upload()方法消费private upload(file: NzUploadFile, fileList: NzUploadFile[]): void { if (!this.options.beforeUpload) { return this.post(file); } const before this.options.beforeUpload(file, fileList); const successBeforeLoadHook (processedFile: NzUploadFile | boolean | Blob | File): void { const processedFileType Object.prototype.toString.call(processedFile); if ( typeof processedFile ! boolean (processedFileType [object File] || processedFileType [object Blob]) ) { (processedFile as NzUploadFile).uid file.uid; // 转换后的文件必须沿用原文件的 uid this.post(file, processedFile as NzUploadFile); } else if (processedFile) { this.post(file); } }; ... if (before instanceof Observable) { before.subscribe({ next: successBeforeLoadHook, error: errorBeforeLoadHook }); } else if (before instanceof Promise) { before.then(successBeforeLoadHook).catch(errorBeforeLoadHook); } else if (before) { return this.post(file); } }这段代码揭示了三个关键机制分支分发返回值是Observable就订阅、是Promise就.then、是同步真值就直接继续上传。转换后的结果统一进入successBeforeLoadHook。Blob/File 判定当回调结果不是布尔值、且原型是[object File]或[object Blob]时说明文件被替换了此时以this.post(file, processedFile)上传新文件否则视为放行上传原始文件。uid 继承源码注释明确指出转换后的文件必须沿用原文件的uid以保证文件列表的追踪、进度上报和删除逻辑一致。3. 真正发出请求时用哪个文件在post()方法中components/upload/upload-btn.component.tsprocessedFile会被放入NzUploadXHRArgs.postFile最终在默认的xhr()实现里通过formData.append(args.name, args.postFile)随请求发送见 components/upload/upload-btn.component.ts。也就是说服务器收到的是转换后的 Blob而不是用户原始文件——这正是上传前转换的最终效果。五、返回值语义速查表结合 components/upload/doc/index.zh-CN.md 的 API 说明与上述源码nzBeforeUpload的返回值语义可归纳如下返回值行为典型用途false同步停止上传格式、大小校验不通过时拦截true同步直接上传原始文件校验通过放行Promiseboolean异步决定放行或拦截异步校验如请求服务端PromiseFile/Blob异步替换后上传新文件异步转换如调用第三方 API 处理图片Observableboolean订阅后按布尔值放行/拦截异步校验流式取消更灵活ObservableFile/Blob订阅后上传转换结果本示例的水印场景补充说明两点放行与替换的区分只有返回非布尔值的File/Blob才会替换上传内容返回true只是放行仍上传原文件。拦截语义官方另一个演示png-only见 components/upload/demo/png-only.md明确指出nzBeforeUpload仅在返回false、Promise.reject()或 Observable 抛出错误时才阻止上传回调抛出的错误会以Unhandled upload beforeUpload error的警告输出见 components/upload/upload-btn.component.ts。六、测试印证Blob 替换上传确实生效仓库中的测试对转换文件行为有直接覆盖。在 components/upload/upload.spec.ts 中it(can return a blob file, () { let ret false; instance.beforeUpload.set((): ObservableNzSafeAny { ret true; return of(new Blob([JSON.stringify(1, null, 2)], { type: application/json })); }); fixture.detectChanges(); pageObject.postSmall(); expect(ret).toBe(true); });同文件中还覆盖了Observable返回true、返回原文件、返回字符串以及返回false取消上传nzChange不被触发、Promise 返回false取消上传、Promise reject 取消上传等多种分支见 components/upload/upload.spec.ts与第四节分析的消费逻辑一一对应。这意味着返回 Blob 继续上传是一条被测试保障的稳定能力你可以放心在生产中使用。七、实战扩展从水印到更多上传前处理掌握了nzBeforeUpload的机制后可以低成本衍生出多种能力1. 图片压缩与缩放复用transformFile的管线在drawImage前按目标尺寸缩放画布即可const scale 0.5; // 压缩到一半尺寸 canvas.width img.width * scale; canvas.height img.height * scale; ctx.drawImage(img, 0, 0, canvas.width, canvas.height);导出的 Blob 体积会显著小于原图适合移动端上传场景。2. 头像上传格式与大小限制官方avatar演示见 components/upload/demo/avatar.md展示了nzBeforeUpload的校验用法点击上传头像时限制图片格式与大小且其说明指出返回值可以是一个 Observable 以支持异步检查配套代码见 components/upload/demo/avatar.ts。3. 上传前异步审核将校验逻辑放入Observable或Promise中先请求服务端确认文件合法性再决定返回true放行或返回false拦截无需改动任何上传代码。八、注意事项IE9 不支持官方 API 文档明确标注nzBeforeUpload在 IE9 下不可用components/upload/doc/index.zh-CN.md。务必使用箭头函数nzBeforeUpload处理函数内部如果依赖组件实例如调用服务箭头函数才能保证this正确指向components/upload/doc/index.zh-CN.md。uid 由组件接管转换后返回 Blob/File 时无需自己生成 uid组件内部会自动沿用原文件的 uidcomponents/upload/upload-btn.component.ts。浏览器 API 依赖FileReader、Canvas、toBlob均为浏览器能力仅适用于支持这些 API 的现代环境Canvas 导出 Blob 时若涉及跨域图片还需注意 CORS 与画布污染问题。小结nzBeforeUpload是 ng-zorro-antd Upload 组件上传前处理的唯一官方入口它既能同步返回布尔值拦截文件也能通过Observable/Promise异步放行更能在返回Blob/File时整体替换上传内容。官方transform-file演示以Canvas 加水印为例串起了 FileReader、Canvas、toBlob 与 RxJS 的完整链路理解了 components/upload/upload-btn.component.ts 中的消费逻辑后图片压缩、格式转换、异步审核等更多定制场景都可以用同样的模式实现。赞分享UI组件前端【免费下载链接】ng-zorro-antdAngular UI Component Library based on Ant Design项目地址https://gitcode.com/gh_mirrors/ng/ng-zorro-antd点击查看免费下载相关推荐Grafana Pyroscope 1.17 发布说明详解Exemplar 查询、符号化性能与稳定性增强Grafana Pyroscope 1.17 发布说明详解Exemplar 查询、符号化性能与稳定性增强 Grafana Pyroscope 1.17.0 是UI组件前端如何使用ng-zorro-antd实现大文件上传高效断点续传完整指南如何使用ng zorro antd实现大文件上传高效断点续传完整指南 ng zorro antd是基于Ant Design设计规范的Angular UI组件库UI组件前端构建安全的PHP命令行应用ShellWrap最佳实践指南构建安全的PHP命令行应用ShellWrap最佳实践指南 在PHP开发中安全地执行命令行操作一直是个挑战。ShellWrap作为一个优雅的PHP命令行包装库开发工具上一篇网易云音乐Web端播放器 NetEaseMusic3 步在本地播放 VIP 与下架歌曲下一篇游戏 DLSS 版本替换不用重装DLSS Swapper 快速上手完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表