在我们的iOS应用程序中,我们有一个UIWebView,它显示我们的域上的网页内容,其中有一个Facebook评论模块。评论模块要求用户登录到facebook。当用户单击登录按钮时,他们将通过登录流程,但永远不会重定向回我们的页面。它们最终会出现在FB拥有的页面上,该页面只会告诉用户“你现在已经登录了”。
再现步骤:
在您登录(步骤3)之后,我期望在成功验证之后,您将被重定向回原始页面(例如http://foo.com/test.htm),以便您可以继续交互。然而,这并没有发生。
相反,你是在一个FB拥有的页面上,只是说类似于“你现在已经登录了”,你被困在那里。不会发生重定向。
这真的是一个bug吗?或者我应该做些什么来确保重定向的发生?
发布于 2016-02-25 20:46:01
如果您只支持iOS 8及更高版本,则可以使用已经实现了@kabuko所述功能的WKWebView
// Container view including the main WKWebView
var container : UIView?
var popupWebView : WKWebView?
override func viewDidLoad() {
super.viewDidLoad()
let prefs = WKPreferences()
prefs.javaScriptEnabled = true
// allow facebook to open the login popup
prefs.javaScriptCanOpenWindowsAutomatically = true
let config = WKWebViewConfiguration()
config.preferences = prefs
webView = WKWebView(frame: container.frame, configuration: config)
webView?.UIDelegate = self
webView?.navigationDelegate = self
}
// callback if the content of the webView wants to create a new window
func webView(webView: WKWebView, createWebViewWithConfiguration configuration: WKWebViewConfiguration, forNavigationAction navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
// create new popup webview and add it to the view hierarchy
popupWebView = WKWebView(frame: container.frame, configuration: configuration)
container.addSubview(popupWebView!)
return popupWebView
}
func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) {
// if the main webView loads a new page (e.g. due to succesful facebook login)
// remove the popup
if (popupWebView != nil) {
popupWebView?.removeFromSuperview()
popupWebView = nil
}
}
发布于 2012-04-06 08:37:04
我见过类似的事情发生在其他网站的FB登录(例如Groupon),如果你在一个UIWebView
中加载它们。如果这是同样的问题(我认为是),这是由于Facebook在弹出窗口中打开了登录窗口,正如您所怀疑的那样。在普通浏览器上发生的情况是,打开另一个窗口(弹出窗口)进行登录,然后当用户登录时,该登录窗口会返回到原始窗口,告知它已登录。他们可能使用EasyXDM或类似的东西。似乎有几层沟通的策略,包括闪存和postMessage
。
在iOS (和安卓)上,这应该意味着它最终将与postMessage
通信。如果你跟踪通过你的UIWebView
的URL,你应该会在末尾看到类似这样的东西:
https://s-static.ak.fbcdn.net/connect/xd_proxy.php#<lots of stuff>&relation=opener&transport=postmessage&<lots more stuff>
UIWebView
不支持多个窗口,所以它不能postMessage
回到你的原始页面,因为它不再被加载。您可以做的是检测UIWebView
何时试图加载FB登录页面,并将其加载到单独的UIWebView
中。现在您有两个窗口可以使用。
不幸的是,这仍然不够,因为当FB页面上的JavaScript试图运行window.opener.postMessage
或window.parent.postMessage
时,它不工作,因为window.parent
和window.opener
没有设置到适当的窗口。我不知道在iOS中有什么好方法可以做到这一点(相比之下,安卓提供了一个合适的API来实现这一点)。
我解决这个问题的方法是编写一个JavaScript对象来包装这些调用。类似于:
window.opener={};
window.opener.postMessage = function(data,url) {
// signal your code in objective-c using some strategy
};
window.parent = window.opener;
有几种方法可以从JavaScript调用Objective-C,包括this one from the official docs。您可以将此代码注入到我在使用stringByEvaluatingJavaScriptFromString:
之前提到的静态FB登录页面。我找不到合适的时间来做这件事,所以我只是在页面加载后注入它,并调用doFragmentSend()
,这是静态页面上的FB JavaScript方法,通常在主体加载时调用。
因此,现在我们需要做的就是通过调用postMessage
将这些数据传递给原始的UIWebView
。它看起来像这样:
NSString *post = [NSString stringWithFormat:@"window.postMessage('%@', '*');", data];
[webView stringByEvaluatingJavaScriptFromString:post];
如果你现在还没有注意到,这是一个巨大的混乱的黑客,我可能不会推荐它,除非你别无选择,但它对我很有效。
发布于 2014-11-27 01:57:35
我也有同样的问题。我发现,在Facebook登录后,UIWebView组件是空的,里面没有html代码。我解决了这个问题,方法是检查webViewDidFinishLoad函数上的UIWebView组件的内容,并在检测到Facebook登录导致白色(空白屏幕)时重新加载其内容:
- (void)webViewDidFinishLoad:(UIWebView *)webView {
if ( [[webView1 stringByEvaluatingJavaScriptFromString:
@"document.body.innerHTML"] isEqualToString:@""] ) {
[webView1 loadRequest:request]; //Define request as you want
}
}
https://stackoverflow.com/questions/8025082
复制相似问题