Le Callback de Facebook ajoute '# = ' pour retourner L'URL

Facebook callback a commencé à ajouter #_=_ hachage de soulignement à L'URL de retour

est-ce que quelqu'un sait pourquoi? Quelle est la solution?

431
demandé sur Deduplicator 2011-08-20 17:05:47

20 réponses

via mises à jour de la plateforme Facebook :

changement dans le comportement de redirection de Session

Cette semaine, nous avons commencé à ajouter un fragment #____=____ à la redirect_uri quand ce champ est laissé vide. Veuillez vous assurer que votre application peut gérer ce comportement.

pour empêcher cela, définissez la redirect_uri dans votre demande d'url de connexion comme suit: (en utilisant Facebook php-sdk)

$facebook->getLoginUrl(array('redirect_uri' => $_SERVER['SCRIPT_URI'],'scope' => 'user_about_me'));

mise à JOUR

ce qui précède est exactement comme la documentation dit de corriger ceci. Cependant, la solution documentée de Facebook ne fonctionne pas. S'il vous plaît envisager de laisser un commentaire sur le mises à jour de la plate-forme Facebook post et de suivre ce bug pour obtenir une meilleure réponse. Jusqu'alors, ajoutez à votre balise head pour résoudre ce problème:

<script type="text/javascript">
    if (window.location.hash && window.location.hash == '#_=_') {
        window.location.hash = '';
    }
</script>

ou une alternative plus détaillée (merci niftylettuce ):

<script type="text/javascript">
    if (window.location.hash && window.location.hash == '#_=_') {
        if (window.history && history.pushState) {
            window.history.pushState("", document.title, window.location.pathname);
        } else {
            // Prevent scrolling by storing the page's current scroll offset
            var scroll = {
                top: document.body.scrollTop,
                left: document.body.scrollLeft
            };
            window.location.hash = '';
            // Restore the scroll offset, should be flicker free
            document.body.scrollTop = scroll.top;
            document.body.scrollLeft = scroll.left;
        }
    }
</script>
225
répondu Ryan 2013-10-16 21:07:04

TL; DR

if (window.location.hash == '#_=_'){
    history.replaceState 
        ? history.replaceState(null, null, window.location.href.split('#')[0])
        : window.location.hash = '';
}

version Complète avec des instructions étape par étape

// Test for the ugliness.
if (window.location.hash == '#_=_'){

    // Check if the browser supports history.replaceState.
    if (history.replaceState) {

        // Keep the exact URL up to the hash.
        var cleanHref = window.location.href.split('#')[0];

        // Replace the URL in the address bar without messing with the back button.
        history.replaceState(null, null, cleanHref);

    } else {

        // Well, you're on an old browser, we can get rid of the _=_ but not the #.
        window.location.hash = '';

    }

}

étape par étape:

  1. nous n'entrerons dans le bloc de code que si fragment est #_=_ .
  2. vérifiez si le navigateur supporte la fenêtre HTML5.méthode du replaceState.
    1. nettoyer L'URL en se divisant sur # et ne prendre que la première partie.
    2. Dis history pour remplacer l'actuel état de la page avec l'URL "propre". Ceci modifie l'entrée de l'histoire actuelle au lieu d'en créer une nouvelle. Cela signifie que les boutons back et forward fonctionneront exactement comme vous le souhaitez. ;- )
  3. si le navigateur ne supporte pas les méthodes impressionnantes D'histoire HTML 5 alors nettoyez juste L'URL comme le meilleur que vous pouvez en mettant le hachage à vide chaîne. Il s'agit là d'une mauvaise solution de rechange, car elle laisse encore derrière elle un hachage (example.com/#) et aussi il ajoute une entrée historique, donc le bouton Précédent vous ramènera à #_-_ .

en savoir plus sur history.replaceState .

en savoir plus sur window.location .

95
répondu PapaSierra 2014-04-23 08:29:14

si vous voulez supprimer le " # "restant de l'url

$(window).on('load', function(e){
  if (window.location.hash == '#_=_') {
    window.location.hash = ''; // for older browsers, leaves a # behind
    history.pushState('', document.title, window.location.pathname); // nice and clean
    e.preventDefault(); // no page reload
  }
})
57
répondu likebeats 2016-05-30 22:54:10

cela a été mis en œuvre par Facebook par conception pour des raisons de sécurité. Voici L'explication d'Eric Osgood, un membre de L'équipe Facebook:

Ce modèle porte la mention "de par sa conception". parce qu'il prévient une vulnérabilité de sécurité potentielle.

certains navigateurs vont ajouter le fragment de hachage d'une URL à la fin d'un nouvelle URL vers laquelle ils ont été redirigés (si cette nouvelle URL ne elle - même ont un fragment de hachage).

par exemple si example1.com renvoie une redirection vers example2.com, puis un navigateur aller à l'exemple1.com # abc ira à l'exemple2.com # abc, et le contenu des fragments de hachage example1.com serait accessible à un script sur example2.com.

Puisqu'il est possible d'avoir un flux auth rediriger vers un autre, il serait possible d'avoir sensibles auth les données d'une application accessible à l'autre.

Ceci est atténué par ajouter un nouveau fragment de hachage à L'URL de redirection pour empêcher ce comportement de navigateur.

si l'esthétique, ou le comportement côté client, de L'URL résultante sont de préoccupation, il serait possible d'utiliser la fenêtre.emplacement.de hachage (ou même une redirection côté serveur de votre propre) pour supprimer le contenu litigieux caractère.

Source: https://developers.facebook.com/bugs/318390728250352 /

26
répondu Mark Murphy 2017-01-29 03:25:34

Je ne sais pas pourquoi ils font ça, mais vous pourriez contourner cela en reprenant le hash en haut de votre page:

if (window.location.hash == "#_=_")
  window.location.hash = "";
10
répondu mixmasteralan 2013-06-21 23:12:12

vous pouvez également spécifier votre propre hachage sur le paramètre redirect_uri pour le rappel Facebook, qui pourrait être utile dans certaines circonstances, par exemple /api/account/callback#home . Lorsque vous êtes redirigé vers l'arrière, ce sera au moins un hachage qui correspond à une route connue si vous utilisez l'épine dorsale.js ou similaire (pas sûr à propos de jQuery mobile).

9
répondu pkiddie 2013-04-30 16:53:35

Facebook utilise un cadre et à l'intérieur de celui-ci tout fonctionne en utilisant la communication AJAX. Le plus gros problème dans ce cas est de préserver l'état actuel de la page. Pour autant que je sache, Facebook a décidé d'utiliser des ancres simulées. Cela signifie que si vous avez cliqué quelque part, ils simulent que comme une ancre à l'intérieur de votre page, et quand la communication AJAX commence, ils changent le point d'ancrage de votre URL aussi bien.

Cette solution vous aide normalement lorsque vous essayez de recharger la page (ne pas entrer, appuyez sur F5 ), parce que votre navigateur envoie toute L'URL avec des ancres au serveur Facebook. Par conséquent, Facebook relève le dernier état (ce que vous voyez) et vous êtes alors en mesure de continuer à partir de là.

lorsque le rappel retourne avec #_=_ cela signifie que la page était dans son état de base avant de la quitter. Parce que cette ancre est analysée par le navigateur, vous n'avez pas besoin de vous inquiéter à ce sujet.

8
répondu Sándor Tóth 2013-01-06 20:30:02

ennuyeux majeur, surtout pour les applications qui analysent L'URI et pas seulement lire le $_GET... Voici le hack, j'ai jeté... Profitez-en!

<html xmlns:fb='http://www.facebook.com/2008/fbml'>
<head>
        <script type="text/javascript">
        // Get rid of the Facebook residue hash in the URI
        // Must be done in JS cuz hash only exists client-side
        // IE and Chrome version of the hack
        if (String(window.location.hash).substring(0,1) == "#") {
                window.location.hash = "";
                window.location.href=window.location.href.slice(0, -1);
                }
        // Firefox version of the hack
        if (String(location.hash).substring(0,1) == "#") {
                location.hash = "";
                location.href=location.href.substring(0,location.href.length-3);
                }
        </script>
</head>
<body>
URI should be clean
</body>
</html>
8
répondu Jeremy Whitt 2013-06-21 23:25:55

cela peut devenir une sorte de problème sérieux si vous utilisez un cadre JS avec hashbang ( / #!/) Url, par exemple Angulaire. En effet, Angular considérera les URL avec un fragment non-hashbang comme invalides et lancera une erreur:

Error: Invalid url "http://example.com/#_=_", missing hash prefix "#!".

si vous êtes dans un tel cas (et rediriger vers votre racine de domaine), au lieu de faire:

window.location.hash = ''; // goes to /#, which is no better

il suffit de faire :

window.location.hash = '!'; // goes to /#!, which allows Angular to take care of the rest
6
répondu neemzy 2013-10-03 10:07:30

Je ne vois pas en quoi ce problème est lié à facebook AJAX. En fait, le problème se produit aussi avec JavaScript désactivé et purement rediriger basé logins.

un exemple d'échange avec facebook:

1. GET <https://www.facebook.com/dialog/oauth?client_id=MY_APP_ID&scope=email&redirect_uri=MY_REDIRECT_URL> RESPONSE 302 Found Location: <https://www.facebook.com/connect/uiserver.php?[...]>  
2. GET <https://www.facebook.com/connect/uiserver.php?[...]> RESPONSE 302 Found MY_REDIRECT_URL?code=FB_CODE#_  
3. GET MY_REDIRECT_URL?code=FB_CODE#_  

N'arrive qu'avec Firefox pour moi aussi.

5
répondu Sebastian Tusk 2013-06-21 23:25:55

ajouter ceci à ma page de redirection a corrigé le problème pour moi ...

if (window.location.href.indexOf('#_=_') > 0) {
    window.location = window.location.href.replace(/#.*/, '');
}
4
répondu neokio 2013-06-21 23:12:25

avec routeur ui angulaire et angulaire, vous pouvez fixer ce

    app.config(function ($stateProvider, $urlRouterProvider, $locationProvider) {

      // Make a trailing slash optional for all routes
      // - Note: You'll need to specify all urls with a trailing slash if you use this method.
      $urlRouterProvider.rule(function ($injector, $location) {
        /***
        Angular misbehaves when the URL contains a "#_=_" hash.

        From Facebook:
          Change in Session Redirect Behavior
          This week, we started adding a fragment #_=_ to the redirect_uri when this field is left blank.
          Please ensure that your app can handle this behavior.

        Fix:
          http://stackoverflow.com/questions/7131909/facebook-callback-appends-to-return-url#answer-7297873
        ***/
        if ($location.hash() === '_=_'){
          $location.hash(null);
        }

        var path = $location.url();

        // check to see if the path already has a slash where it should be
        if (path[path.length - 1] === '/' || path.indexOf('/?') > -1) {
          return;
        }
        else if (path.indexOf('?') > -1) {
          $location.replace().path(path.replace('?', '/?'));
        }
        else {
          $location.replace().path(path + '/');
        }
      });

      // etc ...
    });
});
3
répondu rebelliard 2014-11-14 17:35:39

un changement a été introduit récemment dans la façon dont Facebook gère les redirections de session. Voir "changement dans le comportement de redirection de Session" dans la semaine opération amour développeur post de blog pour l'annonce.

2
répondu Dhiren Patel 2011-09-04 05:32:11

pour moi, je fais une redirection JavaScript vers une autre page pour me débarrasser de #_=_ . Les idées ci-dessous devraient fonctionner. :)

function redirect($url){
    echo "<script>window.location.href='{$url}?{$_SERVER["QUERY_STRING"]}'</script>";        
}
2
répondu Eng Cy 2015-12-13 14:11:28

une solution qui a fonctionné pour moi (en utilisant la colonne vertébrale.js), était d'ajouter "#/" à la fin de L'URL de redirection passé à Facebook. Facebook conservera le fragment fourni, et n'ajoutera pas son propre "_=_".

à son retour, Backbone supprimera la partie"#/". Pour AngularJS, ajouter"#!"à l'URL de retour devrait fonctionner.

notez que l'Identificateur de fragment de L'URL d'origine est conservé lors de la redirection (via les codes D'état HTTP 300, 301, 302 et 303) par la plupart des navigateurs, à moins que L'URL de redirection ait aussi un identificateur de fragment. Ce semble être le comportement recommandé .

si vous utilisez un script de gestionnaire qui redirige l'utilisateur ailleurs, vous pouvez ajouter " # " à L'URL de redirection ici pour remplacer l'Identificateur de fragment par une chaîne vide.

1
répondu Ivo Smits 2015-10-21 10:35:49

je sais que cette réponse est tardive, mais si vous utilisez passportjs, vous pouvez voir ce.

return (req, res, next) => {
    console.log(req.originalUrl);
    next();
};

j'ai écrit cet middleware et je l'ai appliqué à l'instance express server, et L'URL originale que j'ai est sans le "#_=_" . Cela ressemble à cela lorsque nous appliquons l'instance de passporJS comme middleware à l'instance du serveur, il ne prend pas ces caractères, mais sont seulement visibles sur la barre d'adresse de nos navigateurs.

1
répondu Krishna 2017-09-01 21:18:11

j'utilise celui-ci, pour supprimer '#' symbole.

<script type="text/javascript">
    if (window.location.hash && window.location.hash == '#_=_') {
        window.location.href = window.location.href.split('#_=_')[0];
    }
</script>
1
répondu Simon 2017-11-20 17:21:01

en utilisant les routes angulaires 2 (RC5) et à base de hash, je fais ceci:

const appRoutes: Routes = [
  ...
  {path: '_', redirectTo: '/facebookLoginSuccess'},
  ...
]

et

export const routing = RouterModule.forRoot(appRoutes, { useHash: true });

pour autant que je sache, le caractère = dans la route est interprété comme faisant partie de la définition des paramètres de route optionnels (voir https://angular.io/docs/ts/latest/guide/router.html#!#optionnel-route-paramètres ), donc pas impliqué dans la correspondance de route.

0
répondu rcomblen 2016-09-08 14:10:01

Pour PHP SDK utilisateurs

j'ai corrigé le problème simplement en enlevant la pièce supplémentaire avant de l'envoyer.

 $loginURL = $helper->getLoginUrl($redirectURL, $fbPermissions);
 $loginURL = str_replace("#_=_", "", $loginURL);
 header("Location: " . $loginURL);
0
répondu Nanoripper 2018-07-06 20:32:34

cela supprimerait les caractères annexés à votre url

<script type="text/javascript">
 var idx=window.location.toString().indexOf("#_=_"); 
   if (idx > 0) { 
     window.location = window.location.toString().substring(0, idx); 
   } 
</script>
0
répondu Akintunde-Rotimi 2018-10-04 06:19:07