You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular应用如何拦截含嵌入式JavaScript的PDF上传?

如何在Angular中拦截含嵌入式JavaScript的PDF文件上传

完全可以在Angular前端识别并拒绝包含嵌入式JavaScript的PDF文件,核心思路是通过PDF解析库读取文件内部结构,检查是否存在JS相关的动作或脚本。以下是具体实现步骤:

1. 安装PDF解析依赖

使用pdfjs-dist这个主流的PDF解析库,它能在前端解析PDF的内部结构:

npm install pdfjs-dist

2. 组件中实现文件校验逻辑

在负责文件上传的Angular组件中,编写文件上传事件的处理逻辑,解析PDF并检查嵌入式JS:

import { Component } from '@angular/core';
import * as pdfjsLib from 'pdfjs-dist';
import { getDocument } from 'pdfjs-dist';

// 配置pdfjs的worker路径
pdfjsLib.GlobalWorkerOptions.workerSrc = '//cdnjs.cloudflare.com/ajax/libs/pdf.js/4.0.379/pdf.worker.min.js';

@Component({
  selector: 'app-pdf-upload',
  templateUrl: './pdf-upload.component.html',
  styleUrls: ['./pdf-upload.component.css']
})
export class PdfUploadComponent {
  async handleFileUpload(event: Event) {
    const input = event.target as HTMLInputElement;
    if (!input.files || input.files.length === 0) return;

    const file = input.files[0];
    // 基础文件类型校验
    if (file.type !== 'application/pdf') {
      alert('请上传PDF格式文件');
      return;
    }

    try {
      // 将文件转为ArrayBuffer供pdfjs解析
      const arrayBuffer = await file.arrayBuffer();
      const pdf = await getDocument({ data: arrayBuffer }).promise;

      // 检查PDF是否包含JavaScript动作
      const hasEmbeddedJS = await this.checkForEmbeddedJS(pdf);
      
      if (hasEmbeddedJS) {
        alert('禁止上传包含嵌入式JavaScript的PDF文件');
        input.value = ''; // 清空上传框
        return;
      }

      // 校验通过,执行后续上传逻辑
      console.log('文件校验通过,可上传');
      // 调用后端上传接口...
    } catch (error) {
      console.error('PDF解析失败:', error);
      alert('无法解析该PDF文件,请检查文件完整性');
      input.value = '';
    }
  }

  private async checkForEmbeddedJS(pdf: pdfjsLib.PDFDocumentProxy): Promise<boolean> {
    // 检查PDF的OpenAction(打开时触发的动作)
    const metadata = await pdf.getMetadata();
    if (metadata.info?.OpenAction) {
      const openAction = metadata.info.OpenAction.toString();
      if (openAction.includes('JS') || openAction.includes('JavaScript')) {
        return true;
      }
    }

    // 遍历所有页面,检查页面级动作
    for (let i = 1; i <= pdf.numPages; i++) {
      const page = await pdf.getPage(i);
      const pageActions = await page.getActions();
      
      if (pageActions) {
        for (const actionType in pageActions) {
          const action = pageActions[actionType as keyof typeof pageActions];
          if (action?.type === 'JavaScript') {
            return true;
          }
        }
      }
    }

    return false;
  }
}

3. 模板中的上传控件

在组件模板中添加文件上传输入框:

<input type="file" accept=".pdf" (change)="handleFileUpload($event)">

重要提醒

前端校验仅作为第一道防线,必须在后端同步实现相同的PDF校验逻辑。因为前端代码可以被篡改绕过,后端校验才能真正保证系统安全。

内容的提问来源于stack exchange,提问作者user3153356

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 23:31:10