iOS上WKWebView无法加载本地服务器提供的URL

6
我有一个iOS应用程序,尝试在一个线程中运行HTTP Web服务器,并使用单个WKWebView指向该Web服务器的UI(即“Electron”样式的应用程序)。但是,我无法使WKWeView显示 - 甚至不能请求由Web服务器提供的内容。
如果我在Web服务器上进行编程式的HTTP请求,应用程序日志会显示已进行请求,并且响应有效负载包含我预期的内容。
然而,如果我尝试在WKWebView中加载http://127.0.0.1:8000(或任何其他端口),则不会加载任何Web内容。Web服务器甚至没有显示请求被发出。
如果我将Web视图指向HTTPS URL(例如,https://google.com/),它会显示预期的内容。
如果我将Web视图指向HTTP URL(例如,http://neverssl.com/),它会显示预期的内容。
我在WKWebView上安装了导航代理;它显示已开始临时导航,但没有调用其他加载进度委托方法。
应用程序日志中没有其他错误或进度指示器。大约30秒后,我会收到日志消息:
[ProcessSuspension] 0x1321c7eb0 - TimedActivity::activityTimedOut:

再等大约30秒后,我收到了:

2022-10-16 07:54:25.373833-0700 Positron[51762:92124656] [Process] 0x130888218 - [pageProxyID=6, webPageID=7, PID=51772] WebPageProxy::didFailProvisionalLoadForFrame: frameID=3, isMainFrame=1, domain=NSURLErrorDomain, code=-1001, isMainFrame=1

根据错误代码,这似乎是超时问题。但是,在 Web 服务器上没有进行请求,因此不是 Web 服务器超时。

如果我在 macOS 上使用相同的服务器和 WKWebView 代码,将 WKWebView 的 url 设置为 http://127.0.0.1:8000,则会对内部 Web 服务器发出请求,并显示页面。

我在解决此问题时进行了各种搜索,建议是与应用程序权限有关的问题-但是我已经在应用程序的 Info.plist 中设置了可能与此问题相关的所有密钥:

<dict>
    <key>NSAllowsArbitraryLoadsInWebContent</key>
    <true/>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    <key>NSAllowsLocalNetworking</key>
    <true/>
    <key>NSExceptionDomains</key>
    <dict>
        <key>localhost</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSIncludesSubdomains</key>
            <true/>
        </dict>
        <key>127.0.0.1</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSIncludesSubdomains</key>
            <true/>
        </dict>
    </dict>
</dict>

据我所知,大多数这些标签实际上不应该需要,但是为了排除权限问题作为问题源,我已经将它们包含在内。
对于这里发生的情况有什么想法吗?甚至有什么诊断可能正在发生的想法吗?

您是否在一个独立队列中运行服务器?由于WKWebView和服务器必须同时运行,其中WKWebView位于主线程中,而Web服务器位于另一个线程中。 - Ptit Xav
是的-Web服务器在完全独立的线程中运行。我可以在主线程中进行编程Web请求,而这些请求不会阻塞Web服务器。 - freakboy3742
难道不应该是<key>127.0.0.1:80</key>吗?尝试添加端口。 - Lawrence Gimenez
@LawrenceGimenez,它不起作用。实际上需要从WKWebView中禁用访问控制检查,但似乎没有很好的文档说明如何做到这一点。 - Mr Hery
1个回答

1
为了后人的利益 - 我找到了这个问题的答案。问题在于我的应用程序正在使用一些自定义的iOS事件循环,这导致从非主线程排队的事件(包括网络事件)直到在主线程上发生事件刷新事件循环之前都不会被处理。
“手动”修复方法是在GUI中放置一个按钮;即使该按钮未连接到任何内容,由按钮生成的事件足以刷新事件队列,并导致来自后台线程的网络事件加载。
永久修复方法是此PR到Rubicon,已在Rubicon 0.4.4中发布。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接