如何以编程方式“捕获”对 UIWebView 的后向和转发请求?

Posted

技术标签:

【中文标题】如何以编程方式“捕获”对 UIWebView 的后向和转发请求?【英文标题】:How can I "catch" the back and forward requests made to UIWebView programmatically? 【发布时间】:2014-06-18 21:13:31 【问题描述】:

这样的 javascript 调用:

history.goBack();
history.goForward();
history.go(-1);

以编程方式使 UIWebView 后退或前进。在此之前,我需要一种方法来了解用户的去向。你可能会说解决方案是在听委托,但在 UIWebView 上没有合法的响应。

当用户在页面内单击“返回”时调用此委托方法:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType

它的 navigationType 然而设置为 LinkClicked 而不是 BackForward 正如我们预期的那样。我已经从 UIWebView 看到了足够多的疯狂,甚至有点惊讶,但这对我来说是一个死胡同。

我有两个提议:

    创建自定义 JavaScript 方法“myWayOfGoingBack();”并覆盖所有 goBack();方法,所以当它被点击时,我的方法会告诉我将会发生什么。 为上述方法添加一个监听器,但我真的不知道 javascript 是如何工作的。

有什么想法吗?

【问题讨论】:

iosdeveloperzone.com/2011/05/21/… 你好@Vulkan 你有没有设法找到这个问题的任何解决方案?我与您尝试实现的目标相似/接近,并且完全无法控制该网站。 【参考方案1】:

我对你的问题有点困惑。您有一个 UIWebView 用于向用户显示网站,并且该网站内置了可单击的后退和前进按钮/链接?是对的吗?这是您控制的网站,还是您将它们发送到第三方网站?

无论如何,您都想知道 WebView 在加载之前要加载哪个页面。对吗?

问题是(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType) 没有内置的后退/前进导航类型。如果需要,您可以保留他们访问的每个页面的全局数组(在 webview: 函数中更新它),然后比较任何新的请求该列表以查看他们是否再次访问页面。或者你可以注入 JS 来覆盖 javascript 中的链接功能

NSString* js = @"function reportBackToObjectiveC(string)var iframe = document.createElement('iframe');iframe.setAttribute('src', 'callback://' + string);document.documentElement.appendChild(iframe);iframe.parentNode.removeChild(iframe);iframe = null;var links = document.getElementsByTagName('a');for (var i=0; i<links.length; i++) links[i].addEventListener('click', function() reportBackToObjectiveC('SOMETHING_HAPPENED');, true);";
[WebView stringByEvaluatingJavaScriptFromString:js];

(抱歉,这部分内容不能全部显示在屏幕上,它已被压缩以使其可注入。您可以将其复制并粘贴出来并稍微展开以查看实际情况)。

这将为每个链接添加一个事件侦听器,当用户单击链接时,该事件会触发对 URL 回调://SOMETHING_HAPPENED 的请求。然后,您可以在您的委托中过滤这些类型的请求,并据此采取行动。

这有帮助吗?还是我错过了这个问题?

【讨论】:

当用户返回时,我正在尝试实现我自己的动画。如果您单击后退或前进按钮,它可以正常工作,但如果从页面内按下它则不起作用。当我考虑它时,我并没有想到 navigationType 不会起作用。 那么您是否控制您尝试浏览的网页? 绝对无法控制。 好的。唔。我想也许可以试试历史跟踪的东西?保留他们加载的所有页面的列表,如果他们尝试加载他们上次访问的页面,触发你的动画? 我现在正在开发 iOS 8。我试图追踪历史,但它失控了。在 iOS 8 中有一些关键方法,也许再花几天的时间我就能解决这个问题,但我想我会坚持使用 WKBackForwardList 并从那里弄清楚。这使它成为可能,但我希望在没有 BackForwardList 的 iOS7 中有一种方法可以做到这一点。无论如何感谢您的回答。简而言之,iOS 7 缺少完整跟踪历史记录所需的方法,但在 iOS 8 中,您可以在一个简单的列表中获得完整的历史记录。赞美 iOS 8!【参考方案2】:

我知道 JavaScript 无法使用基于历史记录的事件和信息,因为它们希望防止隐私泄露。所以你可以告诉浏览器用前进/后退的方式来处理 JavaScript,但你不知道它是否真的可以前进或后退。

如果您也可以控制 WebView 中的 html,您可以尝试追求 1.People seem to have some succes with it。

【讨论】:

这对我来说很好,但究竟为什么navigationType不是BackForward? Javascript 说 goBack();为什么 UIWebView 的机制如此简单,将其视为 LinkClicked 和 BackForward?天哪

以上是关于如何以编程方式“捕获”对 UIWebView 的后向和转发请求?的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式处理 uiwebview 中的文本字段

如何以编程方式关闭 UIWebView 的上下文菜单?

在 iOS Swift 3 中以编程方式添加 Web 视图时如何在 UIWebView 中获取响应状态代码?

我将如何以编程方式捕获内部音频?

如何以编程方式捕获 iPhone 控制台日志? [关闭]

如何捕获以编程方式更改的 tabBarController setSelectedIndex