为什么我的 XWebView index.html 使用文件方案提供服务,我该如何更改它?
Why is my XWebView served index.html using the file scheme and how do I change it?
我正在使用 WKWebView
来为单页网络应用 (ember) 的 index.html
提供服务,如下所示:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let webview = WKWebView(
frame: view.frame,
configuration: WKWebViewConfiguration()
)
view.addSubview(webview)
let root = NSBundle.mainBundle().resourceURL!
let url = root.URLByAppendingPathComponent("dist/index.html")
webview.loadFileURL(url, allowingReadAccessToURL: root)
加载索引文件效果很好。但是索引文件正在使用文件方案请求它的链接和资源?如果我在检查器中运行时使用 Safari 检查应用程序,我会看到所有本地资源的错误:
[Error] Failed to load resource: ... file:///dist/assets/css/vendor.css
在 index.html
中看起来像:
<link rel="stylesheet" href="./dist/assets/vendor.css">
我想要的是将资源请求转到我的 GCDWebServer,我这样设置:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var webServer: GCDWebServer?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
self.webServer = GCDWebServer()
self.webServer!.addGETHandlerForBasePath("/",
directoryPath: NSBundle.mainBundle().bundlePath,
indexFilename: nil,
cacheAge: 3600,
allowRangeRequests: true
)
self.webServer!.startWithPort(8080, bonjourName: "GCD Web Server")
print("GCD Server running at: \(self.webServer!.serverURL)")
return true
并且我已将 dist
文件夹添加到 Xcode 中的捆绑包中。
我在这里错过了什么?
这就是 HTML 的工作原理。不是绝对的 HREF 是相对于引用页面的来源的。因此,如果您在 file:///dir/index.html
上有 images/foo.png
,浏览器将请求 file:///dir/images/foo.png
。
如果您需要浏览器从其他位置获取资源,则需要在 HTML 中使用绝对 URL(例如 http://localhost:8080/whatever
)。
解决方法很简单。我只需要使用 webview.loadRequest
而不是 webview.loadFileURL
从本地主机为我的 index.html
提供服务,如下所示:
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let serverURL = appDelegate.webServer!.serverURL
let indexURL = serverURL.URLByAppendingPathComponent("dist/index.html")
webview.loadRequest(NSURLRequest(URL: indexURL))
正如 Andrew Medico 所指出的那样,href
是相对于它们的父页面的,因此如果我从本地主机提供 index.html
,那么我的所有资源也会从本地主机请求。解决了。
我正在使用 WKWebView
来为单页网络应用 (ember) 的 index.html
提供服务,如下所示:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let webview = WKWebView(
frame: view.frame,
configuration: WKWebViewConfiguration()
)
view.addSubview(webview)
let root = NSBundle.mainBundle().resourceURL!
let url = root.URLByAppendingPathComponent("dist/index.html")
webview.loadFileURL(url, allowingReadAccessToURL: root)
加载索引文件效果很好。但是索引文件正在使用文件方案请求它的链接和资源?如果我在检查器中运行时使用 Safari 检查应用程序,我会看到所有本地资源的错误:
[Error] Failed to load resource: ... file:///dist/assets/css/vendor.css
在 index.html
中看起来像:
<link rel="stylesheet" href="./dist/assets/vendor.css">
我想要的是将资源请求转到我的 GCDWebServer,我这样设置:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var webServer: GCDWebServer?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
self.webServer = GCDWebServer()
self.webServer!.addGETHandlerForBasePath("/",
directoryPath: NSBundle.mainBundle().bundlePath,
indexFilename: nil,
cacheAge: 3600,
allowRangeRequests: true
)
self.webServer!.startWithPort(8080, bonjourName: "GCD Web Server")
print("GCD Server running at: \(self.webServer!.serverURL)")
return true
并且我已将 dist
文件夹添加到 Xcode 中的捆绑包中。
我在这里错过了什么?
这就是 HTML 的工作原理。不是绝对的 HREF 是相对于引用页面的来源的。因此,如果您在 file:///dir/index.html
上有 images/foo.png
,浏览器将请求 file:///dir/images/foo.png
。
如果您需要浏览器从其他位置获取资源,则需要在 HTML 中使用绝对 URL(例如 http://localhost:8080/whatever
)。
解决方法很简单。我只需要使用 webview.loadRequest
而不是 webview.loadFileURL
从本地主机为我的 index.html
提供服务,如下所示:
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let serverURL = appDelegate.webServer!.serverURL
let indexURL = serverURL.URLByAppendingPathComponent("dist/index.html")
webview.loadRequest(NSURLRequest(URL: indexURL))
正如 Andrew Medico 所指出的那样,href
是相对于它们的父页面的,因此如果我从本地主机提供 index.html
,那么我的所有资源也会从本地主机请求。解决了。