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?
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>
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:
- nous n'entrerons dans le bloc de code que si
fragment
est#_=_
. - vérifiez si le navigateur supporte la fenêtre HTML5.méthode du replaceState.
- nettoyer L'URL en se divisant sur
#
et ne prendre que la première partie. - 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. ;- )
- nettoyer L'URL en se divisant sur
- 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
.
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
}
})
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 /
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 = "";
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).
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.
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>
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
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.
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(/#.*/, '');
}
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 ...
});
});
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.
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>";
}
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.
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.
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>
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.
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);
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>