在 iOS 应用中更改 WKWebView 的来源
Posted
技术标签:
【中文标题】在 iOS 应用中更改 WKWebView 的来源【英文标题】:Change origin of WKWebView in iOS app 【发布时间】:2016-03-05 18:18:11 【问题描述】:我有一个以 WKWebView
为中心的 ios 混合应用程序,使用 loadFileURL
加载本地网络资产。 WKWebView
通过 HTTPS 与带有 jQuery.ajax
的后端 API 通信。该应用程序仅限移动设备,我希望 API 也“仅限移动设备”。也就是说,我想阻止 Chrome 和 Firefox 等浏览器使用 API。
我的策略是在 API 响应中设置 Access-Control-Allow-Origin
标头,如下所示:
Access-Control-Allow-Origin: app://myApp
是否可以将WKWebView
的来源更改为app://myApp
以避免浏览器查询API?
【问题讨论】:
【参考方案1】:案例:1
您可以在创建文档或完成加载文档时将 JS 注入 WKWebview,并将 java 脚本 XMLHTTPRequest open 方法与您的自定义实现挂钩,以便为来自 WKWebView 的所有 AJAX 请求添加此自定义标头。
示例代码
NSString *XMLHTTPRequestHookJSPath = [[NSBundle mainBundle] pathForResource:@"XMLHTTPRequestHook.js" ofType:nil];
NSString *kXMLHTTPRequestHookJS = [NSString stringWithContentsOfFile:XMLHTTPRequestHookJSPath encoding:NSUTF8StringEncoding error:NULL];
WKUserContentController *contentController = [[WKUserContentController alloc] init];
WKUserScript *script = [[WKUserScript alloc] initWithSource:kXMLHTTPRequestHookJS injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:NO];
[contentController addUserScript:script];
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
configuration.userContentController = contentController;
self.lastUsedWebView = [[WKWebView alloc] initWithFrame:self.webContainerView.bounds configuration:configuration];
self.lastUsedWebView.navigationDelegate = self;
在 XMLHTTPRequestHook.js 中尝试将 XMLHttpRequest 与您的自定义实现挂钩,以添加此自定义标头并回调原始打开方法。
案例 2 如果您希望在 WKWebview 中加载 URLRequest 时添加此标头,您可以按如下方式将此标头添加到 NSMutableRequest 并在 WKWebview 中加载此请求。但是,使用此方法,您可能在 WKWebview 的所有 AJAX 调用中都没有此标头。
示例代码:
WKWebView * webView = /*set up your webView*/
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com/index.html"]];
[request addValue:@"app://myApp" forHTTPHeaderField:@"Access-Control-Allow-Origin"];
// use stringWithFormat: in the above line to inject your values programmatically
[webView loadRequest:request];
希望这会有所帮助。
【讨论】:
嗨,钱德拉。在应用程序方面,我希望更改origin
。 Access-Control-Allow-Origin
标头由 API 服务器响应添加!
嗨..如果您正在寻找类似 NSURLProtocol 的东西来拦截来自 WKWebview 的网络请求,NSURLProtocol 不适用于 WKWebview,因为 WKWebview 会加载来自不同进程的所有网络请求。但是,您仍然可以尝试在 case1 中提到的解决方案,将来自 WKWebview 的所有 AJAX 调用的标头更改为所需的值,看看是否有帮助。
另外,您可以更改策略并为来自 WKWebView 的所有 AJAX 调用添加自定义标头(而不是使用 Access-Control-Allow-Origin 标头),您可以在 API 服务器中使用此自定义标头以识别 api 调用来自您的应用程序,而不是来自任何其他浏览器。如果有帮助,请告诉我。
浏览器可以使用 javascript 添加客户标头。从安全角度来看,除非您对 CORS OPTIONS 预检的延迟感到满意,否则这无济于事,我现在就是这样。以上是关于在 iOS 应用中更改 WKWebView 的来源的主要内容,如果未能解决你的问题,请参考以下文章
iOS 9 WKWebView 产生“加载资源失败:已取消”,而 iOS 8 没有
如何在 iOS 应用程序 WkWebView 中调试 javascript?