javascript 如何使用 display: 'iframe' 而不是 'popup' 做 FB.ui({ method: 'auth.login' ...)?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4311289/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 10:57:28  来源:igfitidea点击:

How to do FB.ui({ method: 'auth.login' ...) with display: 'iframe' instead of 'popup'?

javascriptfacebookfacebook-iframe

提问by Weston C

I'm working on a login for a simple Facebook app. I'm able to use the JavaScript SDK to successfully present a login / extended permissions dialog in a popup window with either FB.login or the following code:

我正在登录一个简单的 Facebook 应用程序。我可以使用 JavaScript SDK 在弹出窗口中使用 FB.login 或以下代码成功显示登录/扩展权限对话框:

FB.ui({ method: 'auth.login',
    perms: 'read_stream,publish_stream',
    display: 'popup' },
    function (rsp) {
        fg_log('on login');                             
        if(rsp.session) { 
            if(rsp.perms) {
                fg_log('PERMS: ',rsp.perms);
            } else {
                fg_log('Hmm. No permissions');
            }
        } else {
            fg_log('Hmm. No login');
        }
    }
);

The problem is... I don't like popup windows much. From a UI standpoint, I think they feel off, like they don't belong to the rest of the app. And getting them to show up via JavaScript also require an extra click from the user for no reason -- in order to get around popup blockers, the user has to click on something like a login button (largely pointless, given that by the time the app knows it needs to display a login button, it already knows the user needs to log in and may as well just present the permissions dialog).

问题是...我不太喜欢弹出窗口。从用户界面的角度来看,我认为他们感觉不舒服,就像他们不属于应用程序的其余部分一样。并且让它们通过 JavaScript 显示也需要用户无缘无故的额外点击——为了绕过弹出窗口阻止程序,用户必须点击诸如登录按钮之类的东西(基本上毫无意义,因为到那时应用程序知道它需要显示一个登录按钮,它已经知道用户需要登录并且可能只显示权限对话框)。

So, I thought, why not an iframe instead? No issues with popup blockers, embedded nicely in the page, and Facebook seems to love 'em.

所以,我想,为什么不用 iframe 呢?弹出窗口拦截器没有问题,很好地嵌入页面中,Facebook 似乎很喜欢它们。

A little digging in the recent (2.1.2) JavaScript SDK source and various other posts on the Facebook developers forum seems to indicate one can pass "display: 'iframe'" as part of the options to FB.ui.

对最近(2.1.2)JavaScript SDK 源代码和 Facebook 开发者论坛上的各种其他帖子进行的一些挖掘似乎表明可以将“display: 'iframe'”作为选项的一部分传递给 FB.ui。

But when I try it, though the iframe does come up, instead of getting the permissions dialog, I get:

但是当我尝试它时,虽然 iframe 确实出现了,而不是获得权限对话框,我得到:

"An error occurred with . Please try again later."

“发生错误。请稍后再试。”

(Note: trying again later produces the same results.)

(注意:稍后再试会产生相同的结果。)

is there a trick to get this to work, or is it forbidden for some reason?

有什么技巧可以让它发挥作用,还是出于某种原因被禁止?

回答by Brent Baisley

Try using FB.login instead of FB..ui. If the user is already logged in, and granted the permissions you are asking for via FB.login, then there is no dialog. Otherwise an "inline" one is displayed requesting the extra permissions/login.

尝试使用 FB.login 而不是 FB..ui。如果用户已经登录,并通过 FB.login 授予了您要求的权限,则不会出现对话框。否则会显示一个“内联”请求额外的权限/登录。

It's a little counterintuitive to use a login function to get more permissions when the user is already logged in. But it works.

当用户已经登录时,使用登录功能获得更多权限有点违反直觉。但它有效。

回答by Bruno

Not possible anymore (Jul 2014), but you always could and still can create your own iframe and fill it with a page that redirects from your server to a full page FB login.

不再可能(2014 年 7 月),但您始终可以并且仍然可以创建自己的 iframe,并使用从您的服务器重定向到完整页面 FB 登录的页面填充它。

See https://developers.facebook.com/docs/reference/dialogs/oauth/:

请参阅https://developers.facebook.com/docs/reference/dialogs/oauth/

If you are using the URL redirect dialog implementation, then this will be a full page display, shown within Facebook.com. This display type is called page.

如果您正在使用 URL 重定向对话框实现,那么这将是一个完整的页面显示,显示在 Facebook.com 中。这种显示类型称为页面。

The FB iframe worked at the time the question was asked by either using display: 'iframe'with FB.ui()as Mustafa suggested or using FB.login()(at some points in time it defaulted to 'dialog' mode if FB was properly inited, other times you had to display mode as well).

FB iframe 在提出问题时工作,要么按照 Mustafa 的建议使用display: 'iframe'with FB.ui(),要么使用FB.login()(在某些时候,如果 FB 正确启动,它默认为“对话”模式,其他时候您也必须显示模式)。

This was turned off, most likely early 2014 & due to clickHymaning. From the reference linked above:

这很可能是在 2014 年初和由于点击劫持而关闭的。从上面链接的参考:

If you are using the JavaScript SDK, this will default to a popup window. You can also force the popup or page types when using the JavaScript SDK, if necessary. iframe and async types are not valid for the Login Dialog for security reasons.

如果您使用的是 JavaScript SDK,这将默认为一个弹出窗口。如有必要,您还可以在使用 JavaScript SDK 时强制弹出窗口或页面类型。出于安全原因,iframe 和 async 类型对登录对话框无效。

回答by Mustafa Amin

You can try this:

你可以试试这个:

I use following method approx 6 month ago. :)

我大约 6 个月前使用以下方法。:)

<div>
    <a href="#_" onclick="myOuthDialog();">outh dialog</a>
</div>
<div id="fb-root"></div>
<script>
base_url = 'http/s://path/to/your/site/url';  //Which is set into app setting
myOuthDialog = function(){
    FB.ui({method: 'oauth',
        client_id:'<!--YOUR APP ID-->',
        api_key:'<!--YOUR APP ID-->',
        app_id:'<!--YOUR APP ID-->',
        canvas:'1',
        fbconnect:'1',
        response_type:'code token',
        perms:'email',
        scope:'email',
        redirect_uri:base_url,
        display:'iframe'
    }, myCallback);
}

myCallback = function(data){
    FB.getLoginStatus(function(response) {
      if (response.status === 'connected') {
        document.location = base_url;
        var uid = response.authResponse.userID;
        var accessToken = response.authResponse.accessToken;
      } else if (response.status === 'not_authorized') {
        myOuthDialog();
      } else {
        document.location = base_url;
      }
    }, true);
}
</script>
<script>
  window.fbAsyncInit = function() {
    FB.init({
      appId      : '<!--YOUR APP ID-->', // App ID
      channelUrl : base_url+'channel.php', // Channel File
      status     : true, // check login status
      cookie     : true, // enable cookies to allow the server to access the session
      oauth      : true, // enable OAuth 2.0
      xfbml      : true  // parse XFBML
    });
  };
  (function(d){
     var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
     js = d.createElement('script'); js.id = id; js.async = true;
     js.src = "//connect.facebook.net/en_US/all.js";
     d.getElementsByTagName('head')[0].appendChild(js);
   }(document));
</script>