无法仅将本地 html 文件加载到设备上的 WKWebView 中(适用于模拟器)

Posted

技术标签:

【中文标题】无法仅将本地 html 文件加载到设备上的 WKWebView 中(适用于模拟器)【英文标题】:Cannot load a local html file into a WKWebView on device only (works on simulator) 【发布时间】:2019-10-17 16:46:34 【问题描述】:

下面的本地代码将本地 html 文件加载到 WKWebView 中(来自应用容器,而不是应用包)。

- (void)loadIndexConteneurWithHash:(NSString *)hash

    NSString *fileName = @"index.html";
    NSString *subpath = hash ? [NSString stringWithFormat:@"%@#%@", fileName, hash] : fileName;
    NSString *rootContainerDirectoryPath = [NSFileUtility pathRelativeToContentDirectoryForSubpath:@"/www/v2"];

    NSURL *URL = [NSURL URLWithString:subpath relativeToURL:[NSURL fileURLWithPath:rootContainerDirectoryPath]];

    [[NSURLCache sharedURLCache] removeAllCachedResponses];

    [self.webView loadFileURL:URL allowingReadAccessToURL:URL];



    // This below has the same effect (works on simulator and not on device)

    // NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10.0f];

    // [self.webView performSelectorOnMainThread:@selector(loadRequest:) withObject:request waitUntilDone:true];

设备上的文件地址为:file:///var/mobile/Containers/Data/Application/3CF58895-866D-400A-B0E0-4CA98BF143F7/Library/Application%20Support/<my.app.id>/LocalContents/www/v2/indexConteneur.html

在模拟器上:file:///Users/<me>/Library/Developer/CoreSimulator/Devices/4A5B9713-6589-4DCA-ABBD-F4FF1246AE43/data/Containers/Data/Application/717B54FD-1344-41D3-8B53-FC0767FFE892/Library/Application%20Support/<my.app.id>/LocalContents/www/v2/indexConteneur.html

此代码在我尝试过的任何模拟器(ios 12 / ios 13)上都可以正常工作。

但它不会在设备上加载 HTML 文件。当我使用 Safari 调试器时,我看到 webview 在“about:blank”上。

我在运行时没有错误,它似乎只是默默地停止执行loadFileURL

我可以做些什么来解决/调查这个问题?

编辑 1

didFailNavigation 和 didFinishNavigation 都不会在设备上调用...

编辑 2

添加此代码:

NSFileManager *fileManager = [NSFileManager defaultManager];
NSLog(@"%@ exists? %d",URL.absoluteString,[fileManager fileExistsAtPath:URL.absoluteString]);

在设备上给出这个: 2019-10-17 18:42:48.955588+0200 gall-app[881:230671] /var/mobile/Containers/Data/Application/3CF58895-866D-400A-B0E0-4CA98BF143F7/Library/Application%20Support/<my.app.id>/LocalContents/www/v2/indexConteneur.html exists? 1

所以它存在于预期的位置。我还使用 XCode 从设备下载了应用程序容器,我看到了文件所在的位置。

编辑 3

经过进一步测试,[self.webView loadFileURL:... 似乎不适用于 ios 12(包括模拟器)但适用于 ios 13...

它们之间可能存在一些安全规则差异?

在我的 info.plist 中,我有:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    <key>NSAllowsArbitraryLoadsInWebContent</key>
    <true/>
</dict>

我的 webview 是用这段代码初始化的:

- (void)viewDidLoad

    [super viewDidLoad];
    
    self.webView.UIDelegate = self;
    self.webView.navigationDelegate = self;
    
    self.webView.configuration.preferences.javascriptEnabled = YES;
    self.webView.configuration.preferences.javaScriptCanOpenWindowsAutomatically = YES;
    
    [self.webView.configuration.preferences setValue:@YES forKey:@"allowFileAccessFromFileURLs"];
    [self.webView.configuration setValue:@YES forKey:@"allowUniversalAccessFromFileURLs"];
    
    [self addUserScriptToUserContentController:self.webView.configuration.userContentController];
    

【问题讨论】:

@rmaddy 甚至 decidePolicyForNavigationAction 没有在设备上引发,而在模拟器上引发... 我唯一能想到的就是把[self.webView loadFileURL:URL allowingReadAccessToURL:URL];改成[self.webView loadFileURL:URL allowingReadAccessToURL:URL.URLByDeletingLastPathComponent]; @rmaddy 刚刚尝试过,这是相同的行为。看起来会有某种安全措施阻止它在设备上运行......我的info.plist 有:` NSAppTransportSecurityNSAllowsArbitraryLoadsNSAllowsArbitraryLoadsInWebContent`。我还需要更多吗? @Żabojad 在您的代码中,NSString *subpath = hash ? [NSString stringWithFormat:@"%@#%@", fileName, hash] : fileName; 有一个哈希值,格式说明符中还有一个 #。但是我没有在您的日志中看到您提供的那些(文件名也不同) @MidhunMP 这部分可以忽略,第一个加载的文件没有任何“#”。如果您愿意,hash 为零... 【参考方案1】:

好的,我找到了“为什么”它不起作用。我改变了这个:

[self.webView loadFileURL:URL allowingReadAccessToURL:URL];

到这里:

[self.webView loadFileURL:URL.absoluteURL allowingReadAccessToURL:rootAppURL];

rootAppURL 是:

NSString *rootappPath = [NSFileUtility pathRelativeToContentDirectoryForSubpath:@"/www"];
NSURL *rootAppURL = [NSURL fileURLWithPath:rootappPath isDirectory:YES];

它现在可以在 ios

【讨论】:

我在任何地方都找不到 NSFileUtility 的任何文档。这是 ios 代码库的标准部分吗? 可以分享一下这个方法的代码pathRelativeToContentDirectoryForSubpath吗?

以上是关于无法仅将本地 html 文件加载到设备上的 WKWebView 中(适用于模拟器)的主要内容,如果未能解决你的问题,请参考以下文章

Android SDK Webview加载不在资产文件夹中的本地文件

仅将新文件从 S3 加载到 Redshift 的简单方法?

仅将文本颜色添加到 HTML 上的推文的主题标签

Android上的react-native-webview无法使用ERR_ACCESS_DENIED加载保存在缓存目录中的本地文件[重复]

电脑不能加载本地配置文件

Sencha 2 无法将 html 文件加载到 Android 4.0 上的面板中