文件上的WKWebView iOS 16 Web共享API:协议



我正试图在iOS 16上的WKWebView中运行的文件中使用navigator.share。使用file:协议路径将文件加载到web视图中,如下所示:

uiView.loadFileURL(Bundle.main.url(forResource: "index", withExtension: "html", subdirectory: "web")!, allowingReadAccessTo: Bundle.main.bundleURL)

我打开了这个设置:

configuration.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs")

因此,我可以将file:协议文件加载到web视图中,但似乎无法使用web共享API。我得到这个错误:

NotAllowedError:在当前上下文中,用户代理或平台不允许该请求,可能是因为用户拒绝了权限。

然而,当我将web视图指向此HTTPS URL时,它可以工作:

https://mdn.github.io/dom-examples/web-share

这让我相信Web Share API不起作用,因为通过file:协议加载的HTML文件不安全,因此JavaScript运行时不会将其上的代码视为在安全上下文中运行。

因此,我认为对navigator.shareAPI的访问是被禁止的。

有没有一种方法可以将WKWebView配置为允许访问安全上下文JS/DOM/web API,而无需使用自定义方案(并在从捆绑包加载我的文件的顶部添加一个额外的层(?

问题不在于file:协议或安全上下文。

我查看了navigator.share的WebKit源代码,发现只要不满足瞬态激活的条件,就会返回NotAllowedError

https://github.com/WebKit/WebKit/blob/d9bcb08521ddb86af9a713213d15488712919143/Source/WebCore/page/Navigator.cpp#L172

void Navigator::share(Document& document, const ShareData& data, Ref<DeferredPromise>&& promise)
{
if (!document.isFullyActive()) {
promise->reject(InvalidStateError);
return;
}
if (!validateWebSharePolicy(document)) {
promise->reject(NotAllowedError, "Third-party iframes are not allowed to call share() unless explicitly allowed via Feature-Policy (web-share)"_s);
return;
}
if (m_hasPendingShare) {
promise->reject(InvalidStateError, "share() is already in progress"_s);
return;
}
auto* window = this->window();
if (!window || !window->consumeTransientActivation()) {
promise->reject(NotAllowedError);
return;
}
if (!canShare(document, data)) {
promise->reject(TypeError);
return;
}

瞬态激活是指一些web API只会响应用户手势而运行;用户姿势是导致API调用调用的调用堆栈的一部分,或者用户姿势最近已经发生。

有关瞬态激活的更多信息,请点击此处:https://developer.mozilla.org/en-US/docs/Glossary/Transient_activation

在我的情况下,我确实有一个用户手势,但也有一个WebRTC对等连接ICE收集流,虽然看起来很快,但我猜持续的时间太长了,它重置了短暂激活标志,阻止我在ICE收集阶段结束时使用Web Share API。

修复方法是提前为Web共享API数据负载准备所需的一切,并响应用户的手势,如单击按钮,立即调用Web API。

最新更新