How to fix status code 0 in fetch and XMLHttpRequest for response created by WKURLSchemeHandler

311 Views Asked by At

I need to embed html5 games in my app. (Embed into binary, in a such way that i don't need internet connection). I open index.html with loadHTMLString(htmlContentString, baseURL: "myschemename:///index.html") I implement WKURLSchemeHandler and face strange problem: XMLHttpRequest and fetch request gets status code "0" and response.ok "false", despite the fact that I returned the data from WKURLSchemeHandler

WKURLSchemeHandler code:

class MyURLSchemeHandler: NSObject, WKURLSchemeHandler {
  func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) {
    let fileData = ...// code that find file on disk and read it
    urlSchemeTask.didReceive(URLResponse(
        url: urlSchemeTask.request.url!,
        mimeType: fileURL.mimeType(),
        expectedContentLength: fileData.count,
        textEncodingName: "utf-8")
    )
    urlSchemeTask.didReceive(fileData)
    urlSchemeTask.didFinish()
  }
}

Html code that is

<!DOCTYPE html>
<html>
    <script>
        fetch("myschemename:///data.json")
            .then((response) => {
                if (response.ok) {
                    console.log("ok");
                } else {
                    console.log("error");
                }
            });
    </script>
    <body>
    </body>
</html>
1

There are 1 best solutions below

0
On

URLResponse have status code 0 as default value. The correct way is to use HTTPURLResponse instead of URLResponse and set 200 status code:

class MyURLSchemeHandler: NSObject, WKURLSchemeHandler {
    func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) {
        let fileData = ...// code that find file on disk and read it
        var headerFields = urlSchemeTask.request.allHTTPHeaderFields ?? [:]
        /*
          We must provide "Content-Type" and "Content-Length" headers or we would face 
          "WebPageProxy::didFailProvisionalLoadForFrame domain=WebKitErrorDomain, code=102"
        */
        headerFields["Content-Type"] = fileURL.mimeType()
        headerFields["Content-Length"] = "\(fileData.count)"
        urlSchemeTask.didReceive(HTTPURLResponse(
            url: urlSchemeTask.request.url!,
            statusCode: 200,
            httpVersion: "HTTP/1.1",
            headerFields: headerFields
        )!)
        urlSchemeTask.didReceive(fileData)
        urlSchemeTask.didFinish()
    }
}