Обратный звонок Facebook добавляет '# _ = _' к URL возврата - PullRequest
455 голосов
/ 20 августа 2011

Обратный вызов Facebook начал добавлять хэш-символ #_=_ к обратному URL

Кто-нибудь знает почему?Какое решение?

Ответы [ 21 ]

232 голосов
/ 04 сентября 2011

через Обновления платформы Facebook :

Изменение в поведении перенаправления сеанса

На этой неделе мы начали добавлять фрагмент # ____ = ____ к redirect_uri, когда это поле оставлено пустым. Пожалуйста, убедитесь, что ваше приложение может справиться с этим поведение.

Чтобы предотвратить это, установите redirect_uri в вашем URL-адресе для входа в систему следующим образом: (используя Facebook php-sdk)

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

UPDATE

Вышесказанное в точности соответствует документации , чтобы исправить это. Однако документированное решение Facebook не работает. Пожалуйста, оставьте комментарий в блоге Обновления платформы Facebook и следуйте этой ошибке , чтобы получить лучший ответ. До этого добавьте следующее в тег head для решения этой проблемы:

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

Или более подробная альтернатива (спасибо 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>
107 голосов
/ 19 августа 2013

TL; DR

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

Полная версия с пошаговыми инструкциями

// 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 = "";

    }

}

Шаг за шагом:

  1. Мы попадем в блок кода, только если fragment равен #_=_.
  2. Проверьте, поддерживает ли браузер метод window5.replaceState в HTML5.
    1. Очистите URL, разделив # и выбрав только первую часть.
    2. Скажите history, чтобы заменить текущее состояние страницы чистым URL. Это изменяет текущую запись истории вместо создания новой. Это означает, что кнопки «назад» и «вперед» будут работать так, как вы хотите. ; -)
  3. Если браузер не поддерживает удивительные методы истории HTML 5, просто очистите URL как можно лучше, установив хэш в пустую строку. Это плохой запасной вариант, поскольку он по-прежнему оставляет конечный хеш (example.com/#), а также добавляет запись в историю, поэтому кнопка возврата вернет вас к #_-_.

Подробнее о history.replaceState.

Подробнее о window.location.

58 голосов
/ 09 апреля 2012

, если вы хотите удалить оставшиеся "#" из 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
  }
})
37 голосов
/ 29 января 2017

Это было реализовано Facebook специально для безопасности.Вот объяснение Эрика Осгуда, Эрика Осгуда, члена команды Facebook:

Это было помечено как «разработанное», поскольку оно предотвращает потенциальную уязвимость безопасности.

Некоторые браузеры добавляют хэшфрагмент от URL-адреса до конца нового URL-адреса, на который они были перенаправлены (если этот новый URL-адрес сам по себе не содержит хеш-фрагмент).

Например, если example1.com возвращает перенаправление на example2.comзатем браузер, идущий на example1.com # abc, перейдет на example2.com # abc, и содержимое фрагмента хеша из example1.com будет доступно для скрипта на example2.com.

Поскольку это возможночтобы перенаправить один поток аутентификации в другой, было бы возможно иметь конфиденциальные данные аутентификации из одного приложения, доступного для другого.

Это можно уменьшить, добавив новый хеш-фрагмент к URL-адресу перенаправления, чтобы предотвратить такое поведение браузера.

Если эстетика или поведение на стороне клиента итогового URL-адреса вызывает беспокойство, можно было бы использоватьwindow.location.hash (или даже ваше перенаправление на стороне сервера) для удаления оскорбительных символов.

Источник: https://developers.facebook.com/bugs/318390728250352/

10 голосов
/ 21 августа 2011

Не знаю, зачем они это делают, но вы можете обойти это, сбросив хеш в верхней части своей страницы:

if (window.location.hash == "#_=_")
  window.location.hash = "";
9 голосов
/ 30 апреля 2013

Вы также можете указать свой собственный хэш в параметре redirect_uri для обратного вызова Facebook, который может быть полезен при определенных обстоятельствах, например. /api/account/callback#home. Когда вы будете перенаправлены назад, это будет, по крайней мере, хеш, который соответствует известному маршруту, если вы используете backbone.js или аналогичный (не уверен насчет jquery mobile).

8 голосов
/ 01 января 2012

Основная раздражает, особенно для приложений, которые анализируют URI, а не просто читают $ _GET ... Вот хак, который я бросил вместе ... Наслаждайтесь!

<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 голосов
/ 25 августа 2011

Facebook использует фрейм, и внутри него все функционирует, используя AJAX-связь.Самая большая проблема в этом случае - сохранение текущего состояния страницы.Насколько я понимаю, Facebook решил использовать смоделированные анкеры.Это означает, что если вы нажали где-то, они имитируют это как привязку внутри вашей страницы, а когда начинается связь AJAX, они также меняют бит привязки вашего URL.

Это решение обычно помогает вам, когда вы пытаетесьчтобы перезагрузить страницу (не ENTER, нажмите F5 ), потому что ваш браузер отправляет весь URL с привязками на сервер Facebook.Поэтому Facebook выбирает последнее состояние (то, что вы видите), и вы можете продолжить с него.

Когда обратный вызов возвращается с #_=_, это означает, что страница находилась в своем базовом состоянии дочтобы оставить его.Поскольку этот якорь анализируется браузером, вам не нужно беспокоиться об этом.

6 голосов
/ 03 октября 2013

Это может стать серьезной проблемой, если вы используете JS-фреймворк с URL-адресами hashbang (/ #! /), Например, Angular.Действительно, Angular будет считать недействительными URL-адреса с фрагментом без хэш-банга и выдаст ошибку:

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

Если вы находитесь в таком случае (и перенаправляете в корень своего домена), вместо выполнения:1004 *

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

Просто сделайте:

window.location.hash = '!'; // goes to /#!, which allows Angular to take care of the rest
5 голосов
/ 26 августа 2011

Не вижу, как эта проблема связана с Facebook AJAX. На самом деле проблема также возникает с отключенным JavaScript и чисто перенаправленным входом в систему.

Пример обмена с фейсбуком:

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#_  

Случается только с Firefox для меня тоже.

...