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

如何在.NET Core中检测PDF文档中的JavaScript脚本?

在.NET Core中检测PDF中的JavaScript(无需付费库)

完全可以不用付费库实现这个功能,下面提供几种可行的思路和实现方案:

方案1:简单文本匹配(快速筛查)

PDF的核心结构是文本格式的,JavaScript相关逻辑通常会携带/JS、/JavaScript、/AA(附加动作)或javascript:这类特定标记。我们可以直接读取PDF内容,过滤掉注释(PDF注释以%开头)后检查这些标记。

这种方案优点是实现简单、速度快,适合做初步检测;缺点是可能存在误报(比如文本内容恰好包含这些字符串)。

示例代码:

using System.IO;
using System.Text;
using System.Linq;

public bool HasJavaScriptSimple(string pdfPath)
{
    // PDF默认采用ASCII编码,部分包含特殊字符的可能用UTF-8
    var pdfContent = File.ReadAllText(pdfPath, Encoding.ASCII);
    var jsMarkers = new[] { "/JS", "/JavaScript", "/AA", "javascript:" };
    
    foreach (var line in pdfContent.Split('\n'))
    {
        var trimmedLine = line.Trim();
        // 跳过PDF注释行
        if (trimmedLine.StartsWith("%")) continue;
        if (jsMarkers.Any(marker => trimmedLine.Contains(marker)))
        {
            return true;
        }
    }
    return false;
}

方案2:轻量级PDF对象解析(更准确)

PDF由多个对象(格式为[编号] [版本] obj ... endobj)组成,JavaScript通常存储在对象的字典结构中。我们可以通过正则匹配提取所有PDF对象,再在对象内容中查找JS相关标记,排除注释干扰。

这种方案比文本匹配更准确,但需要处理PDF的基本对象结构;如果遇到压缩后的PDF(比如用FlateDecode压缩的对象),还需要额外处理解压逻辑(可以用.NET Core自带的DeflateStream实现)。

示例代码:

using System.IO;
using System.Text;
using System.Text.RegularExpressions;

public bool HasJavaScriptAdvanced(string pdfPath)
{
    var pdfContent = File.ReadAllText(pdfPath, Encoding.ASCII);
    // 匹配所有PDF对象
    var objRegex = new Regex(@"\d+\s+\d+\s+obj(.*?)endobj", RegexOptions.Singleline);
    var objMatches = objRegex.Matches(pdfContent);
    
    foreach (Match match in objMatches)
    {
        var objContent = match.Groups[1].Value;
        foreach (var line in objContent.Split('\n'))
        {
            var trimmedLine = line.Trim();
            if (trimmedLine.StartsWith("%")) continue;
            if (trimmedLine.Contains("/JS") || trimmedLine.Contains("/JavaScript"))
            {
                return true;
            }
        }
    }
    return false;
}

方案3:使用免费开源PDF库(最可靠)

如果需要更准确、全面的检测,推荐使用iText 7 Community Edition——这是一款免费开源的PDF处理库,完全支持.NET Core,能处理复杂的PDF结构(包括压缩对象、页面动作、表单字段动作等)。

示例代码:

using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Action;

public bool HasJavaScriptWithItext(string pdfPath)
{
    using var pdfReader = new PdfReader(pdfPath);
    using var pdfDoc = new PdfDocument(pdfReader);
    
    // 检查文档级全局JavaScript
    if (pdfDoc.GetCatalog().GetPdfObject().GetAsDictionary(PdfName.JavaScript) != null)
    {
        return true;
    }
    
    // 检查页面附加动作(如打开/关闭页面时的JS)
    for (int pageNum = 1; pageNum <= pdfDoc.GetNumberOfPages(); pageNum++)
    {
        var page = pdfDoc.GetPage(pageNum);
        var pageActions = page.GetPdfObject().GetAsDictionary(PdfName.AA);
        if (pageActions != null && HasJsAction(pageActions))
        {
            return true;
        }
    }
    
    // 检查表单字段的JavaScript动作
    var form = pdfDoc.GetForm();
    if (form != null)
    {
        foreach (var field in form.GetFields())
        {
            var fieldActions = field.GetPdfObject().GetAsDictionary(PdfName.AA);
            if (fieldActions != null && HasJsAction(fieldActions))
            {
                return true;
            }
        }
    }
    
    return false;
}

// 辅助方法:检查动作字典中是否包含JS动作
private bool HasJsAction(PdfDictionary actionDict)
{
    foreach (var key in actionDict.KeySet())
    {
        var action = actionDict.GetAsDictionary(key);
        if (action != null && PdfName.JS.Equals(action.GetAsName(PdfName.S)))
        {
            return true;
        }
    }
    return false;
}

注意事项

  • 如果选择自己解析PDF,需要注意处理压缩对象:PDF中部分对象会用FlateDecode压缩,此时需要先读取压缩的字节流,用DeflateStream解压后再解析内容。
  • iText 7 Community Edition完全免费,可通过NuGet直接安装(包名:itext7)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 23:25:59