Javascript 带有文件url的WKWebView xmlhttprequest
我正在使用app documents文件夹中的本地HTMLs从UIWebView迁移到WKWebView。 我可以加载包含所有css和js文件的索引页面,但是由于允许的访问来源,每个ajax调用(xmlhttprequest)都会失败Javascript 带有文件url的WKWebView xmlhttprequest,javascript,ios,ajax,wkwebview,Javascript,Ios,Ajax,Wkwebview,我正在使用app documents文件夹中的本地HTMLs从UIWebView迁移到WKWebView。 我可以加载包含所有css和js文件的索引页面,但是由于允许的访问来源,每个ajax调用(xmlhttprequest)都会失败 我不想在我的应用程序中使用Web服务器,因为我认为它会过大。我怎样才能做到这一点?该应用程序是一个简单的HTML5应用程序,用于内部应用程序。设备无法联机,或者任何安全功能都可能被完全禁用。对于那些通过此功能找到此主题的用户: 这不是正式关闭WKWebView中的
我不想在我的应用程序中使用Web服务器,因为我认为它会过大。我怎样才能做到这一点?该应用程序是一个简单的HTML5应用程序,用于内部应用程序。设备无法联机,或者任何安全功能都可能被完全禁用。对于那些通过此功能找到此主题的用户: 这不是正式关闭WKWebView中的安全性,但我们可以使用私有API来实现这一点,就像这家伙在Cordova项目中所做的那样: 线索是为WebView创建配置并设置allowFileAccessFromFileURLs属性
WKWebViewConfiguration* configuration = originalImpSend(_self, selector, settings);
// allow access to file api
@try {
[configuration.preferences setValue:@TRUE forKey:@"allowFileAccessFromFileURLs"];
}
@catch (NSException *exception) {}
@try {
[configuration setValue:@TRUE forKey:@"allowUniversalAccessFromFileURLs"];
}
@catch (NSException *exception) {}
return configuration;
但正如我提到的,这是私有API,这可能是在苹果的应用程序审查中拒绝你的应用程序的一个原因。如果您想在App Store中发布应用程序,请考虑运行一些轻量级HTTP服务器,而不是违反Web视图的整体安全性。示例:。这解决了我的问题:
let config = WKWebViewConfiguration()
config.userContentController = contentController
config.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs")
webView = WKWebView(frame: .zero, configuration: config)
webView.uiDelegate = self
webView.navigationDelegate = self
view = webView
因此,当我第一次尝试它时,accepted对我不起作用(当时我做得不对),它强烈建议不要做的关于()的bug。我的解决方案是实现一个自定义url方案,并使用它加载所有文件。看起来像这样 首先创建附加了url方案的WKWebView(必须自己创建WKWebView,不能在情节提要上创建) 然后实现处理程序
import Foundation
import WebKit
import MobileCoreServices
class PrayerAssetHandler: NSObject, WKURLSchemeHandler {
func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) {
let url = urlSchemeTask.request.url!
let pathArr = url.path.components(separatedBy: ".")
let forResource: String = pathArr[0]
let ofType: String? = pathArr.count > 1 ? pathArr[1] : nil
let bundlePath = Bundle.main.path(forResource: "data_sub_folder" + forResource, ofType: ofType)
let fileExtension: CFString = ofType! as CFString
guard
let extUTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension,
fileExtension, nil)?.takeUnretainedValue()
else { return }
guard
let mimeUTI: NSString = UTTypeCopyPreferredTagWithClass(extUTI,
kUTTagClassMIMEType)?.takeRetainedValue()
else { return }
let mimeType: String = mimeUTI as String
do {
let data: Data = try NSData(contentsOfFile: bundlePath!) as Data
//Create a NSURLResponse with the correct mimetype.
let urlResponse = URLResponse(url: url, mimeType: mimeType,
expectedContentLength: data.count, textEncodingName: "utf8")
urlSchemeTask.didReceive(urlResponse)
urlSchemeTask.didReceive(data)
urlSchemeTask.didFinish()
} catch _ as NSError {
return
}
}
func webView(_ webView: WKWebView, stop urlSchemeTask: WKURLSchemeTask) {
}
}
哇,谢谢你!经过这段时间,我终于可以从UIWebView迁移到WKWebView了。你的解决方案对我来说很好。谢谢你的例子!这里有两件事并不明显:要加载带有自定义方案的页面,您必须提供自己的navigationDelegate来确认您的请求。还要记住,
NSResponse
没有状态代码,会导致XMLHttpUrlRequests失败(和/或像axios这样的库)。改用NSHttpUrlResponse
。
import Foundation
import WebKit
import MobileCoreServices
class PrayerAssetHandler: NSObject, WKURLSchemeHandler {
func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) {
let url = urlSchemeTask.request.url!
let pathArr = url.path.components(separatedBy: ".")
let forResource: String = pathArr[0]
let ofType: String? = pathArr.count > 1 ? pathArr[1] : nil
let bundlePath = Bundle.main.path(forResource: "data_sub_folder" + forResource, ofType: ofType)
let fileExtension: CFString = ofType! as CFString
guard
let extUTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension,
fileExtension, nil)?.takeUnretainedValue()
else { return }
guard
let mimeUTI: NSString = UTTypeCopyPreferredTagWithClass(extUTI,
kUTTagClassMIMEType)?.takeRetainedValue()
else { return }
let mimeType: String = mimeUTI as String
do {
let data: Data = try NSData(contentsOfFile: bundlePath!) as Data
//Create a NSURLResponse with the correct mimetype.
let urlResponse = URLResponse(url: url, mimeType: mimeType,
expectedContentLength: data.count, textEncodingName: "utf8")
urlSchemeTask.didReceive(urlResponse)
urlSchemeTask.didReceive(data)
urlSchemeTask.didFinish()
} catch _ as NSError {
return
}
}
func webView(_ webView: WKWebView, stop urlSchemeTask: WKURLSchemeTask) {
}
}