Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Facebook login hangs at "XD Proxy" when page is installed via Chrome Web Store

The created the following web application:

http://www.web-allbum.com/

I also added it to the Chrome Web Store:

https://chrome.google.com/webstore/detail/idalgghcnjhmnbgbeebpdolhgdpbcplf

The problem is that when go to the Chrome Web Store and install this app the Facebook login windows hangs at a "XD Proxy" window. While the connect itself works, this blank window can confuse the users.

I did my research, and this seems to be a Chrome issue: https://code.google.com/p/chromium/issues/detail?id=59285#c26

If you uninstall the app from Chrome, the problem disappears.

Is there any workaround for this problem?

Similar stackoverflow questions:

  • Facebook connect login window locking in Chrome
  • FB.login dialog does not close on Google Chrome
  • facebook connect blank pop up on chrome
  • https://stackoverflow.com/questions/4423718/blank-page-with-fb-connect-js-sdk-on-after-permission-request

This is my Facebook connect in case it helps:

    FB.init({
        appId  : window.__FACEBOOK_APP_ID__,
        status : true, // check login status
        cookie : true, // enable cookies to allow the server to access the session
        xfbml  : true, // parse XFBML
        channelUrl : window.__MEDIA_URL__ + 'channel.html', // channel.html file
        oauth  : true // enable OAuth 2.0
    });


    FB.XD.Flash.init();
    FB.XD._transport = "flash";

    if (A.networks.facebook.connected) {
        FB.getLoginStatus(function (response) {
            // Stores the current user ID for later use
            that.network_id = response.authResponse.userID;

            if (!response.authResponse) {
                // no user session available, someone you dont know
                A.networks.facebook.connected = false;
            }
            callback();
        });
    }
    else {
        callback();
    }
}; 

The Solution

Thanks to the reekogi reply I was able to workaround this issue. Here is the full implementation:

In order to avoid the XD Proxy problem, you have to connecte to Facebook without using the FB.login, this can be achieved by manually redirecting the user to Facebook page.

I had this login function in my code:

_facebook.connect_to_network = function (callback) {
    FB.login(function (response) {
        if (response.authResponse) {
            console.log('Welcome!  Fetching your information.... ');
            FB.api('/me', function (response) {
                // Stores the current user Id for later use
                that.network_id = response.id;
                console.log('Good to see you, ' + response.name + '.');
                callback();
            });
        }
        else {
            console.log('User cancelled login or did not fully authorize.');
            that.connected = false;
            callback();
        }

    }, {scope: window.__FACEBOOK_PERMS__});
};

Which I replaced by this code:

_facebook.connect_to_network = function (callback) {
    var url = 'https://www.facebook.com/connect/uiserver.php?app_id=' + window.__FACEBOOK_APP_ID__ + '&method=permissions.request&display=page&next=' + encodeURIComponent(window.__BASE_URL__ + 'authorize-window?my_app=facebook&my_method=login') + '&response_type=token&fbconnect=1&perms=' + window.__FACEBOOK_PERMS__;

    window.open(url);
};

The new code opens a popup which connects to Facebook and returns to the url specified in the 'next' parameter. I added some extra parameters in this callback url so that the javascript code could check for it and close the popup.

This code is executed when the Facebook redirects to the callback url:

_facebook.parse_url_params = function () {
    // This is the popup window
    if (URL_PARAMS.my_method === 'login') {
        window.opener.A.networks.facebook.connected = true;
        self.close();
    }
};

URL_PARAMS is just a helper object that contains all the url parameters.

I still believe that this is a Chrome issue, but since this workaround has worked and solved my problem I am marking this question as solved.

like image 377
Cesar Canassa Avatar asked Sep 10 '11 00:09

Cesar Canassa


5 Answers

Could you call a javascript redirect to get permissions then redirect back to the http://www.web-allbum.com/connected uri?

I described this method in detail here -> Permissions on fan page

EDIT:

The method I demonstrated before will be deprecated when OAuth 2.0 comes into the requirements.

Here is the code, adapted for OAauth 2.0 (response.session is replaced with response.authResponse)

<div id="fb-root"></div>
<script>
theAppId = "YOURAPPID";
redirectUri = "YOURREDIRECTURI"; //This is the page that you redirect to after the user accepts the permissions dialogue

//Connect to JS SDK
FB.init({
    appId  : theAppId,
    cookie: true, 
    xfbml: true, 
    status: true,
    channelURL : 'http://yourdomain.co.uk/channel.html', // channel.html file
    oauth  : true // enable OAuth 2.0
});

//Append to JS SDK to div.fb-root
(function() {
    var e = document.createElement('script');
    e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
    e.async = true;
    document.getElementById('fb-root').appendChild(e);
}());

//Check login status and permissions
FB.getLoginStatus(function(response) {
  if (response.authResponse) {
    // logged in and connected user, someone you know
  } else {
    //Redirect to permissions dialogue
    top.location="https://www.facebook.com/connect/uiserver.php?app_id=" + theAppId + "&method=permissions.request&display=page&next=" + redirectUri + "&response_type=token&fbconnect=1&perms=email,read_stream,publish_stream,offline_access";
  }
});

</script>

Just tried and tested, worked fine in chrome.

like image 120
rgdigi Avatar answered Nov 16 '22 03:11

rgdigi


I didn't try the solution proposed by Cesar, because I prefer to stick with Facebook's official javascript SDK.

Nevertheless I would like to add a few observations:

  • Indeed, the blocking problem only happened on Chrome after installing from Chrome Web Store. Uninstalling the web app solves the problem. (tested with legacy authentication method, without oauth 2.0). After closing the XD Proxy popup manually, my application was working properly.

  • After switching to asynchronous FB.init() and enabling oauth 2.0 option, my application would not even get a valid facebook connect status at login time ({authResponse: null, status: "unknown"})... Again, uninstalling it from the Chrome Web Store, it's working... ({authResponse: Object, status: "connected"})

  • No problem encountered with Safari, in any of these cases.

like image 24
Adrien Joly Avatar answered Nov 16 '22 03:11

Adrien Joly


In IE8 - this can be caused by your flash version. I tried everything and nothing worked until I disabled flash. More details from this blog:http://hustoknow.blogspot.com/2011/06/how-facebooks-xdproxyphp-seemed-to-have.html#comment-form

like image 44
ambiguousFoo Avatar answered Nov 16 '22 03:11

ambiguousFoo


Open a new browser tab in Chrome and see if you have the Facebook 'App' installed. If so, drag it to the bottom right corner to uninstall. Once uninstalled the XD Proxy will work.

Reference: facebook connect blank pop up on chrome

like image 40
jwriddle Avatar answered Nov 16 '22 02:11

jwriddle


I was experiencing same problem for all browsers. When user clicked "login" button, a popup opened and hanged; and unless user killed browser process, it caused a high load on CPU. If user managed to see "allow" button and click it however, then it appeared a "xd proxy" blank window and nothing happened. That was the problem.

After long investigations, I noticed my new JS code which proxies setInterval/clearInterval/setTimeout/clearTimeout methods, caused this problem. Code is as follows:

window.timeoutList = new Array();
window.intervalList = new Array();

window.oldSetTimeout = window.setTimeout;
window.oldSetInterval = window.setInterval;
window.oldClearTimeout = window.clearTimeout;
window.oldClearInterval = window.clearInterval;

window.setTimeout = function(code, delay) {
    window.timeoutList.push(window.oldSetTimeout(code, delay));
};
window.clearTimeout = function(id) {
    var ind = window.timeoutList.indexOf(id);
    if(ind >= 0) {
        window.timeoutList.splice(ind, 1);
    }
    window.oldClearTimeout(id);
};
window.setInterval = function(code, delay) {
    window.intervalList.push(window.oldSetInterval(code, delay));
};
window.clearInterval = function(id) {
    var ind = window.intervalList.indexOf(id);
    if(ind >= 0) {
        window.intervalList.splice(ind, 1);
    }
    window.oldClearInterval(id);
};
window.clearAllTimeouts = function() {
    for(var i in window.timeoutList) {
        window.oldClearTimeout(window.timeoutList[i]);
    }
    window.timeoutList = new Array();
};
window.clearAllIntervals = function() {
    for(var i in window.intervalList) {
        window.oldClearInterval(window.intervalList[i]);
    }
    window.intervalList = new Array();
};

Removing these lines solved my problem. Maybe it helps to who experiences the same.

like image 28
Gokhan Ozturk Avatar answered Nov 16 '22 04:11

Gokhan Ozturk



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!