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

.NET MAUI iOS端使用PDF.js加载AppData目录PDF文件失败

.NET MAUI iOS中PDF.js加载AppData目录PDF失败的解决方案

问题场景

在.NET MAUI iOS应用中,使用PDF.js的viewer.html加载AppData目录中的PDF文件时,仅显示工具栏但文档内容为空。直接用WebView加载PDF绝对路径可正常显示,Android端加载也正常,仅iOS端出现问题;加载应用包内的测试PDF则能正常显示。

核心原因

iOS的WKWebView对file://协议的跨源访问有严格限制:应用包内的资源(路径前缀为file:///var/containers/Bundle/...)和AppData目录的资源(路径前缀为file:///private/var/mobile/Containers/Data/...)属于不同的文件域,默认禁止跨域访问,导致PDF.js无法加载跨域的本地PDF文件。

解决方案1:调整WKWebView配置+路径编码

步骤1:完善WKWebView权限配置

修改WebViewHandler的映射代码,添加跨域访问本地文件的权限:

Microsoft.Maui.Handlers.WebViewHandler.Mapper.AppendToMapping("newPdfView", (handler, view) =>
{
#if ANDROID
    handler.PlatformView.Settings.JavaScriptEnabled = true;
    handler.PlatformView.Settings.AllowFileAccess = true;
    handler.PlatformView.Settings.AllowFileAccessFromFileURLs = true;
    handler.PlatformView.Settings.AllowUniversalAccessFromFileURLs = true;
#else
    if (handler.PlatformView is WebKit.WKWebView wkWebView) 
    {
        wkWebView.Configuration.Preferences.SetValueForKey(Foundation.NSObject.FromObject(true), new Foundation.NSString("allowFileAccessFromFileURLs"));
        // 添加允许跨域访问本地文件的配置
        wkWebView.Configuration.Preferences.SetValueForKey(Foundation.NSObject.FromObject(true), new Foundation.NSString("allowUniversalAccessFromFileURLs"));
    }
#endif
});

步骤2:对PDF路径进行合法URL编码

避免路径中的特殊字符(如空格、中文)导致URL解析失败,通过Uri对象生成标准的file://链接:

#if IOS
var pdfFilePath = Foundation.NSBundle.MainBundle.PathForResource("pdfjs/web/viewer", "html");
// 获取AppData中PDF的完整路径
string pdfFullPath = Path.Combine(FileSystem.Current.AppDataDirectory, "Cataloghi", pdf.Descrizione + ".pdf");
// 生成合法的file://格式URL
Uri pdfUri = new Uri(pdfFullPath);
string encodedPdfUrl = pdfUri.AbsoluteUri;
// 拼接viewer.html的访问路径
string path = $"file://{pdfFilePath}?file={encodedPdfUrl}";
newPdfView.Source = new UrlWebViewSource{ Url = path};
#elif ANDROID
newPdfView.Source = $"file:///android_asset/pdfjs/web/viewer.html?file=file:{WebUtility.UrlEncode(Path.Combine(FileSystem.AppDataDirectory, "Cataloghi", pdf.Descrizione + ".pdf"))}";
#endif

解决方案2:将PDF.js资源复制到AppData目录

把应用包内的PDF.js相关文件(viewer.html、viewer.js、viewer.css及依赖资源)复制到AppData目录,让viewer和PDF处于同一文件域,彻底解决跨域问题:

#if IOS
// 定义PDF.js资源的源目录和目标目录
string viewerAssetDir = Path.Combine(Foundation.NSBundle.MainBundle.BundlePath, "pdfjs", "web");
string viewerTargetDir = Path.Combine(FileSystem.Current.AppDataDirectory, "pdfjs", "web");

// 复制整个web目录(包含所有PDF.js依赖资源)
if (!Directory.Exists(viewerTargetDir))
{
    Directory.CreateDirectory(viewerTargetDir);
    // 复制文件
    foreach (var file in Directory.GetFiles(viewerAssetDir))
    {
        string destFile = Path.Combine(viewerTargetDir, Path.GetFileName(file));
        if (!File.Exists(destFile)) File.Copy(file, destFile);
    }
    // 复制子目录(如images、locale等)
    foreach (var dir in Directory.GetDirectories(viewerAssetDir))
    {
        string destDir = Path.Combine(viewerTargetDir, Path.GetFileName(dir));
        if (!Directory.Exists(destDir))
        {
            Directory.CreateDirectory(destDir);
            foreach (var file in Directory.GetFiles(dir))
            {
                string destFile = Path.Combine(destDir, Path.GetFileName(file));
                if (!File.Exists(destFile)) File.Copy(file, destFile);
            }
        }
    }
}

// 加载AppData目录下的viewer.html
string viewerTargetPath = Path.Combine(viewerTargetDir, "viewer.html");
string pdfFullPath = Path.Combine(FileSystem.Current.AppDataDirectory, "Cataloghi", pdf.Descrizione + ".pdf");
Uri pdfUri = new Uri(pdfFullPath);
string path = $"file://{viewerTargetPath}?file={pdfUri.AbsoluteUri}";
newPdfView.Source = new UrlWebViewSource{ Url = path};
#endif

解决方案3:修改PDF.js的viewer.js(可选)

如果不想移动PDF.js资源,可以修改viewer.js中的跨域检查逻辑:
打开pdfjs/web/viewer.js,找到以下代码块(通常在文件开头):

if (origin !== viewerOrigin && protocol !== "blob:") {
  throw new Error("file origin does not match viewer's");
}

注释或删除这段代码,允许PDF.js加载不同域的本地文件。注意:这种方式可能存在安全风险,仅在信任本地文件来源的场景使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 11:22:06