Facebook Geri Arama, Dönüş URL'sine '# _ = _' ekler


479

Facebook geri araması #_=_, Dönüş URL'sine karma alt çizgi eklemeye başladı

Nedenini bilen var mı? Çözüm nedir?


35
Facebook'un bu karakterleri nasıl eklediğine dair bir fikrin var mı? Facebook, işleyicime yönlendiriyor ve burada geri dönüş URL'sine yönlendirmeyi işliyorum, ancak karakterler hala URL'ye ekleniyor.
Ben Foster

4
@BenFoster Fiddler veya benzeri bir şey kullandığınızı göreceksiniz, FB işleyicinize yeniden yönlendirildiğinde, #_=_yerinde, o Response.Redirectzaman gerçekten yapmak istediğiniz bir yere yapsanız bile , tarayıcı hash'i korur , bu yüzden yalnızca aşağıda önerilen istemci tarafı geçici çözümleri çalışır.
AakashM

17
2017, ne zuck
Ejonas GGgg

6
Mayıs 2017, hala ....
Mirko

5
Mart 2018 .. evet hala oluyor
John Rogerson

Yanıtlar:


239

Facebook'un Platform Güncellemeleri aracılığıyla :

Oturum Yönlendirme Davranışındaki Değişiklik

Bu hafta, bu alan boş bırakıldığında redirect_uri'ye # ____ = ____ parçası eklemeye başladık. Lütfen uygulamanızın bu davranışı gerçekleştirebildiğinden emin olun.

Bunu önlemek için, giriş URL'si isteğinizdeki redirect_uri'yi şu şekilde ayarlayın: (Facebook php-sdk kullanarak)

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

GÜNCELLEME

Yukarıdaki belge tam olarak bunu düzeltmek için söylediği gibidir. Ancak, Facebook'un belgelenmiş çözümü çalışmıyor. Lütfen Facebook Platform Güncellemeleri blog yayınına yorum bırakmayı ve daha iyi bir yanıt almak için bu hatayı takip etmeyi düşünün . O zamana kadar, bu sorunu çözmek için kafa etiketinize aşağıdakileri ekleyin:

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

Veya daha ayrıntılı bir alternatif (teşekkürler şıklığı ):

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

10
hangi alan boş bırakılır? Bu çok şifreli
user210504

11
@Ryan Update neredeyse benim için çalışıyor, sonunda bir karma (/ #) alıyorum. FB'den memnun değil.
LenPopLilly

2
Hala / # alıyorum. burada güncelleme yapan var mı? # kaldırıldı almak için
Tian Loon

6
Bu çözüm hash: <script type = "text / javascript"> var idx = window.location.toString (). İndexOf ("# _ = _"); if (idx> 0) {window.location = window.location.toString (). substring (0, idx); } </script> Bunun, head öğesindeki ilk etiket olduğundan emin olun.
Gorgi Rankovski

1
Hata raporunuzu burada fark ettim: developers.facebook.com/bugs/1424488987806270 Aynı sonucu "fragment request_uri" de aramayı denedim.
Ryan

115

TL; DR

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

Adım adım talimatlar içeren tam sürüm

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

    }

}

Adım adım:

  1. Eğer Biz sadece kod bloğunun içine alırsınız fragmentolduğunu #_=_.
  2. Tarayıcının HTML5 window.replaceStateyöntemini destekleyip desteklemediğini kontrol edin .
    1. URL'yi bölerek #ve yalnızca ilk bölümü alarak temizleyin .
    2. historyGeçerli sayfa durumunu temiz URL ile değiştirmeyi söyleyin . Bu, yeni bir giriş oluşturmak yerine geçerli geçmiş girişini değiştirir. Bunun anlamı, geri ve ileri düğmelerinin tam istediğiniz gibi çalışmasıdır. ;-)
  3. Tarayıcı harika HTML 5 geçmiş yöntemlerini desteklemiyorsa, karma değerini boş dizeye ayarlayarak URL'yi mümkün olan en iyi şekilde temizleyin. Bu kötü bir geri dönüştür, çünkü hala arkada bir karma bırakır (example.com/#) ve ayrıca bir geçmiş girişi ekler, böylece geri düğmesi sizi geri götürür #_-_.

Hakkında daha fazla bilgi edinin history.replaceState.

Hakkında daha fazla bilgi edinin window.location.


2
Benim için de mükemmel çalıştı. Diğer çözüm, sorgu parametrelerinden kurtulur.
AdeelMufti

Google omniauth için de aynı şey geçerli, bu yüzden hiçbir rota eşleşmesi hatası alıyorum, istek sonra # (hashtag) ekliyor uri https: //.....herokua‌ pp.com/auth/google_oa‌ uth2 / callback? durumu = 1‌ 9feaacfe23423jh5jhhGS‌ DFwb419049ebb18dabdf8‌ & code = 4 / glrY3-mSlTzwe‌ rwERTEG334eXcn3hOSxGu‌ c51BAlglPa4AU #
Shalafister'ın

Sorguyu silmediği için benim için @Ryan çözümünden daha iyi çalıştı.
olivmir

Bu çözüm Ryan'ın çözümünden daha iyi çalıştı. Facebook'un kimlik doğrulaması ve Ryan'ın çözümü aracılığıyla URL'ye bazı parametreler iletiyorum, bazı nedenlerden dolayı her parametreyi URL'den kaldırıyor. Bu çözüm benim durumumda mükemmel çalışıyor.
BlueSun3k1

59

URL'den kalan "#" işaretini kaldırmak istiyorsanız

$(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
  }
})

6
$ (window) .on ('load', fonksiyon (e) {/ * likebeats'in kodu * /} çalışıyor.
ISHITOYA Kentaro

1
i değiştirerek bu kodu kullanın e.preventDefault (); event.preventDefault ();
printf

Bu kod jQuery ve bağımsız değişkeni alan bir onWindowReady olay dinleyicisi olduğunu varsayar e.
Jason Sperske

49

Bu, güvenlik nedenleriyle Facebook tarafından tasarım tarafından uygulanmıştır. İşte bir Facebook Ekibi üyesi Eric Osgood'un açıklaması:

Bu, potansiyel bir güvenlik açığını önlediğinden 'tasarım gereği' olarak işaretlenmiştir.

Bazı tarayıcılar, karma parçasını bir URL'den yönlendirildikleri yeni bir URL'nin sonuna ekler (bu yeni URL'nin kendisinde bir karma parçası yoksa).

Örneğin example1.com, example2.com'a bir yönlendirme döndürürse, example1.com # abc adresine giden bir tarayıcı example2.com # abc'ye gider ve example1.com'daki karma parça içeriğine example2 üzerindeki bir komut dosyası erişilebilir .com.

Bir kimlik doğrulaması akışının bir başkasına yönlendirilmesi mümkün olduğundan, bir uygulamadan diğerine erişilebilen hassas kimlik doğrulama verilerine sahip olmak mümkün olacaktır.

Bu, tarayıcı davranışını önlemek için yönlendirme URL'sine yeni bir karma parçası eklenerek azaltılır.

Ortaya çıkan URL'nin estetiği veya istemci tarafı davranışı endişe ediyorsa, rahatsız edici karakterleri kaldırmak için window.location.hash (veya kendi sunucu tarafı yönlendirmesini) kullanmak mümkün olacaktır.

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


9
Bunun neden olduğunu açıklayan tek cevap bu, teşekkürler, sanırım sorun olmayan karakterleri url'lerimde bırakacağım.
stephenmurdoch

1
Bu, Tumblr tarafından yönlendirmelerinde de uygulanır. ('19 ortası itibariyle) FB açıklamasına işaret ettiğiniz için teşekkür ederiz. Basit bir Passport uygulamasında kolayca başarılı bir şekilde yönlendirmeyi sadece "/" yerine "/ #" 'ye işaret ederek çözdüm (bu da neden web'de daha fazla ahtapot gördüğümü açıklıyor, sanırım ...)
RL Brown

10

Bunu neden yaptıkları konusunda emin değilsiniz, ancak sayfanızın üst kısmındaki karma değerini sıfırlayarak bunun üstesinden gelebilirsiniz:

if (window.location.hash == "#_=_")
  window.location.hash = "";

9

Ayrıca redirect_uri, Facebook geri arama parametresinde kendi karmasını da belirtebilirsiniz ; bu, belirli durumlarda yardımcı olabilir /api/account/callback#home. Geri yönlendirdiğinizde, en azından backbone.js veya benzeri bir yöntem kullanıyorsanız (jquery mobile'dan emin değilseniz) bilinen bir rotaya karşılık gelen bir karma olacaktır.


8

Facebook bir çerçeve kullanır ve içindeki her şey AJAX iletişimini kullanarak çalışır. Bu durumda en büyük sorun geçerli sayfa durumunu korumaktır. Anladığım kadarıyla, Facebook simüle çapa kullanmaya karar verdi. Bu, bir yere tıkladıysanız, bunu sayfanızın içinde bir bağlantı olarak simüle eder ve AJAX iletişimi başladığında, URL'nizin bağlantı bitini de değiştirir.

Bu çözüm, sayfayı yeniden yüklemeye çalıştığınızda (ENTER değil, basın F5) normalde size yardımcı olur , çünkü tarayıcınız tüm URL'yi çapalarla Facebook sunucusuna gönderir. Bu nedenle Facebook en son durumu (gördüklerinizi) alır ve oradan devam edebilirsiniz.

Geri arama #_=_bununla birlikte döndüğünde sayfanın ayrılmadan önce temel durumunda olduğu anlamına gelir. Bu çapa tarayıcı tarafından ayrıştırıldığı için endişelenmenize gerek yok.


2
Omurga veya kor gibi bir javascript çerçeveniz varsa, karma işleminden sonra her şey yönlendirici tarafından yorumlandığı için bu bir sorundur
Rudi

1
URL parçası tanımlayıcıları ("çapalar") istek üzerine tarayıcıya gönderilmez . Ayrıca, bu soru ana masaüstü sitesi hakkında değil OAuth ile ilgilidir. Bunun nedeni, kötü amaçlı yönlendirme URI'sinin hazırlanması nedeniyle saldırıları önleyen OAuth güvenliği .
AndrewF

8

Özellikle URI'yi ayrıştıran ve sadece $ _GET'i okumakla kalmayan uygulamalar için büyük can sıkıcı ... İşte birlikte attığım hack ... Keyfini çıkarın!

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

Oluşturmadığınız verileri ayrıştırırken varsayımlarda bulunmaya dikkat edin. URI parça tanımlayıcıları RFC 1738 (1994'te) kadar erken belirtilmiştir, bu nedenle doğru bir URI ayrıştırıcı kullanırsanız, bu hiçbir zaman sorun olmamalıdır.
AndrewF

6

Hashbang (/ #! /) URL'lerine sahip bir JS çerçevesi kullanıyorsanız, örneğin Angular gibi, bu ciddi bir sorun haline gelebilir. Gerçekten de, Angular, karma olmayan bir parçaya sahip URL'leri geçersiz olarak kabul eder ve bir hata atar:

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

Böyle bir durumda (ve alan adı köküne yönlendiriyorsanız) yapmak yerine:

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

Basitçe yapın:

window.location.hash = '!'; // goes to /#!, which allows Angular to take care of the rest

1.2+, bu harika çalışıyor. 1.0 ve altı sürümler için window.location.hash = '';
Pradeep Mahdevu

1
Evet, bunu sadece 1.2'de test ettim, şartname için teşekkürler!
neemzy

Ve sonra html5 modu var
rocketspacer

5

Bu sorunun facebook AJAX ile nasıl ilişkili olduğunu görmüyorum. Aslında bu sorun, JavaScript devre dışı bırakıldığında ve yalnızca temel girişleri yeniden yönlendirirken de ortaya çıkar.

Facebook ile örnek değişim:

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

Benim için sadece Firefox ile olur.


4

Bunu yönlendirme sayfama eklemek sorunu benim için çözdü ...

if (window.location.href.indexOf('#_=_') > 0) {
    window.location = window.location.href.replace(/#.*/, '');
}

1
bu, sayfa yenilemesini başlatan bir pencere konum değişikliğine neden olur
rpearce

3

Açısal ve açısal UI yönlendirici ile bunu düzeltebilirsiniz

    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 ...
    });
});

burada çalışmaz - rota () uygulanmadan önce rota değişir
Maël Nison

3

Vue-router kullanıyorsanız, rota listesine ekleyebilirsiniz:

{
  path: '/_=_',
  redirect: '/', // <-- or other default route
},

2

Son zamanlarda Facebook'un oturum yönlendirmelerini işleme biçiminde bir değişiklik yapıldı. Duyuru için bu haftanın Operation Developer Love blog gönderisinde "Oturum Yeniden Yönlendirme Davranışında Değişiklik" konusuna bakın .


1
Emin değilim, o burada ne ifade ediyor
user210504

2

Benim için, kurtulmak için başka bir sayfaya JavaScript yönlendirmesi yapıyorum #_=_. Aşağıdaki fikirler işe yarar. :)

function redirect($url){
    echo "<script>window.location.href='{$url}?{$_SERVER["QUERY_STRING"]}'</script>";        
}

Bu Birden yararsız istekleri oluştururken çünkü bence iyi bir fikir değil
Jacek Pietal

1

Benim için çalışan bir geçici çözüm (Backbone.js kullanarak), Facebook'a iletilen yönlendirme URL'sinin sonuna "# /" eklemekti. Facebook sağlanan parçayı koruyacak ve kendi "_ = _" ifadesini eklemeyecektir.

Geri döndüğünde, Omurga "# /" kısmını kaldıracaktır. AngularJS için "#!" dönüş URL'sinin çalışması gerekir.

Yönlendirme URL'sinde de bir parça kimliği yoksa, orijinal URL'nin parça tanımlayıcısının çoğu tarayıcı tarafından yeniden yönlendirmede (HTTP durum kodları 300, 301, 302 ve 303 aracılığıyla) korunduğunu unutmayın. Bu önerilen bir davranış gibi görünüyor .

Kullanıcıyı başka bir yere yönlendiren bir işleyici komut dosyası kullanırsanız, parça tanımlayıcısını boş bir dize ile değiştirmek için yönlendirme URL'sine "#" ekleyebilirsiniz.


1

Bu cevabın geç olduğunu biliyorum, ancak passportjs kullanıyorsanız, bunu görmek isteyebilirsiniz.

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

Bu ara katman yazılımı yazdım ve sunucu örneğini ifade etmek için uyguladım ve aldığım orijinal URL "#_=_". PassporJS örneğini sunucu örneğine ara katman yazılımı olarak uyguladığımızda, bu karakterleri almaz, ancak yalnızca tarayıcılarımızın adres çubuğunda görünür gibi görünür.


3
"# _ = _" yalnızca istemcide kullanılabilir. İnceleme: en.wikipedia.org/wiki/Fragment_identifier
alditis

1

Ben de '#' sembolünü silmek için kullanıyorum.

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

0

Açısal 2 (RC5) ve karma tabanlı rotaları kullanarak, bunu yaparım:

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

ve

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

Anladığım kadarıyla =, rotadaki karakter isteğe bağlı rota parametreleri tanımının bir parçası olarak yorumlanır (bkz. Https://angular.io/docs/ts/latest/guide/router.html#!#optional-route-parameters ) , bu nedenle rota eşleşmesine dahil değildir.


0

PHP SDK kullanıcıları için

Yönlendirmeden önce fazladan parçayı kaldırarak sorunu çözdüm.

 $loginURL = $helper->getLoginUrl($redirectURL, $fbPermissions);
 $loginURL = str_replace("#_=_", "", $loginURL);
 header("Location: " . $loginURL);

0

Bu, URL'nize eklenen karakterleri kaldıracaktır

<script type="text/javascript">
 var idx=window.location.toString().indexOf("#_=_"); 
   if (idx > 0) { 
     window.location = window.location.toString().substring(0, idx); 
   } 
</script>

0

"# _ = _" (PHP) kaldırmak için en kolay ve temiz çözüm:

"Header (" Location: xxx.php ");" yerine "echo (" location.href = 'xxx.php'; ");"

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.