फ़ेसबुक कॉलबैक, URL वापस करने के लिए '# _ = _' करता है


479

फेसबुक कॉलबैक ने #_=_रिटर्न यूआरएल पर हैश अंडरस्कोर को जोड़ना शुरू कर दिया है

क्या किसी को पता है क्यों? उपाय क्या है?


35
किसी भी विचार कैसे फेसबुक इन पात्रों को जोड़ता है? फेसबुक मेरे हैंडलर को रीडायरेक्ट करता है जहां मैं फिर से रिटर्न यूआरएल पर पुनर्निर्देशन संभालता हूं, फिर भी पात्रों को अभी भी यूआरएल से जोड़ा जाता है।
बेन फोस्टर

4
@BenFoster मुझे लगता है कि यदि आप Fiddler या इसी तरह का उपयोग करते हैं तो आप पाएंगे कि जब FB आपके हैंडलर को रिड्यूक्ट करता #_=_है, तब वह जगह पर होता है, तब भी आप एक ऐसा करते हैं Response.Redirectजहां आप वास्तव में करना चाहते हैं, ब्राउज़र हैश बनाए रखता है , यही वजह है कि यह केवल क्लाइंट-साइड वर्कअराउंड है जो नीचे सुझाया गया है जो काम करेगा।
आकाश

17
2017, क्या zuck
Ejonas GGgg

6
मई 2017, अभी भी ....
मिरको

5
मार्च 2018..आप अभी भी हो रहा है
जॉन

जवाबों:


239

फेसबुक के प्लेटफॉर्म अपडेट के माध्यम से :

सत्र अनुप्रेषित व्यवहार में बदलाव

इस सप्ताह, हमने इस फ़ील्ड को खाली छोड़ देने पर # ____ = ____ को एक खंड जोड़ना शुरू किया। कृपया सुनिश्चित करें कि आपका ऐप इस व्यवहार को संभाल सकता है।

इसे रोकने के लिए, अपने लॉगिन url अनुरोध में रीडायरेक्ट_यूरी सेट करें जैसे: (फेसबुक php-sdk का उपयोग करके)

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

अपडेट करें

ऊपर ठीक वैसा ही है जैसा कि दस्तावेज़ इसे ठीक करने के लिए कहता है। हालांकि, फेसबुक का डॉक्यूमेंटेड सॉल्यूशन काम नहीं करता है। कृपया फेसबुक प्लेटफॉर्म अपडेट्स ब्लॉग पोस्ट पर एक टिप्पणी छोड़ने पर विचार करें और बेहतर जवाब पाने के लिए इस बग का पालन करें । तब तक, इस समस्या को हल करने के लिए अपने मुख्य टैग में निम्नलिखित जोड़ें:

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

10
किस क्षेत्र को खाली छोड़ दिया गया है? यह बहुत ही गूढ़ है
user210504

11
@ रयान अपडेट मेरे लिए लगभग काम करता है, मुझे अभी भी अंत में एक हैश (/ #) मिलता है। एफबी से खुश नहीं।
लेनपोपली

2
मुझे अभी भी / # मिलता है। किसी को भी यहाँ अद्यतन? # हटाए जाने के लिए
तियान लोन

6
यह समाधान हैश मिटा देगा: <स्क्रिप्ट प्रकार = "पाठ / जावास्क्रिप्ट"> var idx = window.location.toString ()। indexOf ("# _ = _"); if (idx> 0) {window.location = window.location.toString ()। सबस्ट्रिंग (0, idx); } </ script> यह सुनिश्चित करें कि यह मुख्य तत्व का पहला टैग है।
गोरगी रेंकोवस्की

1
मैंने आपकी बग रिपोर्ट को यहाँ देखा: Developers.facebook.com/bugs/1424488987806270 मैंने उसी परिणाम के साथ "टुकड़ा अनुरोध_ सुरी" की खोज में अपना हाथ आजमाया।
रयान

115

टी एल; डॉ

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. जांचें कि ब्राउज़र HTML5 window.replaceStateविधि का समर्थन करता है या नहीं ।
    1. URL को #केवल पहले भाग पर विभाजित करके साफ करें ।
    2. बताओ historyसाफ यूआरएल के साथ वर्तमान पृष्ठ राज्य को बदलने के लिए। यह एक नया बनाने के बजाय वर्तमान इतिहास प्रविष्टि को संशोधित करता है। इसका मतलब यह है कि आगे और पीछे बटन आपके इच्छित तरीके से काम करेंगे। ;-)
  3. यदि ब्राउज़र भयानक एचटीएमएल 5 इतिहास के तरीकों का समर्थन नहीं करता है, तो बस यूआरएल को खाली स्ट्रिंग पर हैश सेट करके सबसे अच्छा साफ कर लें। यह एक खराब वापसी है क्योंकि यह अभी भी एक पीछे चल रहा हैश (उदाहरण.com/#) को छोड़ता है और यह एक इतिहास प्रविष्टि भी जोड़ता है, इसलिए बैक बटन आपको वापस ले जाएगा #_-_

के बारे में अधिक जानें history.replaceState

के बारे में अधिक जानें window.location


2
मेरे लिए भी पूरी तरह से काम किया। अन्य समाधान किसी भी क्वेरी पैरामीटर से छुटकारा दिलाता है।
आदिलमुफ्ती

यह Google omniauth के लिए एक ही बात करता है, इसलिए मुझे कोई त्रुटि नहीं मिलती है जो रूट से मेल खाता है, यह uri https: //.....herokuah pp.com/auth/google_oah uth2 / कॉलबैक के अनुरोध के बाद # (हैशटैग) जोड़ देता है। राज्य = 1 ह 9feaacfe23423jh5jhGSh DFwb419049ebb18dabdf8h & code = 4 / glrY3-mSlTzwe rwERTEG33eXcn3hOSxGuh c51BAlglPa4AU #
Shalafister

मेरे लिए @Ryan के समाधान से बेहतर काम किया, क्योंकि यह क्वेरी को नहीं हटाता है।
ओलिवमीर

इस समाधान ने रयान के समाधान से बेहतर काम किया। मैं फेसबुक के प्रमाणीकरण और रयान के समाधान के बाद कुछ यूआरएल के मापदंडों को पास करता हूं, किसी कारण से हर पैरामीटर को यूआरएल से हटा देता है। यह समाधान मेरे मामले में पूरी तरह से काम करता है।
BlueSun3k1

59

यदि आप 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
  }
})

6
$ (विंडो) .on ('लोड', फंक्शन (e) {/ * likebeats का कोड * /} काम करता है।
ISHITOYA Kentaro

1
मैं इस कोड को e.preventDefault () बदलकर उपयोग करता हूं; to event.preventDefault ();
printf

यह कोड jQuery मान रहा है, और एक onWindowReady इवेंट श्रोता तर्क ले रहा है e
जेसन स्पर्सके

49

इसे सुरक्षा कारणों से फेसबुक द्वारा डिजाइन द्वारा लागू किया गया था। यहाँ फेसबुक टीम के सदस्य एरिक ओसगूड से स्पष्टीकरण लिया गया है:

इसे 'डिज़ाइन द्वारा' के रूप में चिह्नित किया गया है क्योंकि यह संभावित सुरक्षा भेद्यता को रोकता है।

कुछ ब्राउज़र एक नए 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/


9
यह एकमात्र ऐसा उत्तर है जो वास्तव में बताता है कि ऐसा क्यों होता है, धन्यवाद, मुझे लगता है कि मैं अपने उरोजों में अपमानजनक आकर्षण छोड़ दूँगा अब मुझे पता है कि वे एक मुद्दा नहीं हैं।
Stephenmurdoch

1
यह भी Tumblr द्वारा उनके पुनर्निर्देश में लागू किया गया है। (मिड -19 के रूप में) एफबी स्पष्टीकरण की ओर इशारा करने के लिए धन्यवाद। आसानी से एक सरल पासपोर्ट ऐप में केवल "/ #" के बजाय "/ #" के सफल पुनर्निर्देशन को इंगित करके हल किया गया है (जो बताता है कि मुझे वेब पर अधिक अनुगामी ऑक्टोथोरप्स क्यों दिखाई देते हैं, मुझे लगता है ...)
आरएल ब्राउन

10

सुनिश्चित नहीं हैं कि वे ऐसा क्यों कर रहे हैं, लेकिन आप अपने पृष्ठ के शीर्ष पर हैश रीसेट करके इसे प्राप्त कर सकते हैं:

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

9

आप redirect_uriफेसबुक कॉलबैक के लिए पैरामीटर पर अपना स्वयं का हैश निर्दिष्ट कर सकते हैं , जो कुछ विशेष परिस्थितियों में सहायक हो सकता है /api/account/callback#home। जब आप वापस रीडायरेक्ट होते हैं, तो यह कम से कम एक हैश होगा जो एक ज्ञात मार्ग से मेल खाती है यदि आप बैकबोन.जेएस या समान (जेकरी मोबाइल के बारे में निश्चित नहीं) का उपयोग कर रहे हैं।


8

फेसबुक एक फ्रेम का उपयोग करता है और इसके अंदर AJAX संचार का उपयोग करके सब कुछ कार्य करता है। इस मामले में सबसे बड़ी समस्या वर्तमान पृष्ठ स्थिति को संरक्षित करना है। जहां तक ​​मैं समझता हूं, फेसबुक ने नकली एंकर्स का इस्तेमाल करने का फैसला किया। इसका मतलब है कि यदि आप कहीं क्लिक करते हैं, तो वे अनुकरण करते हैं कि आपके पृष्ठ के अंदर एक एंकर के रूप में, और जब AJAX संचार शुरू होता है, तो वे आपके URL के एंकर बिट को भी बदलते हैं।

जब आप पृष्ठ को पुनः लोड करने की कोशिश करते हैं (एनआरआर नहीं, तो प्रेस करें F5 ), , क्योंकि आपका ब्राउज़र फेसबुक सर्वर पर एंकर के साथ पूरा URL भेजता है। इसलिए फेसबुक नवीनतम स्थिति (जो आप देखते हैं) को चुनता है और फिर आप वहां से जारी रखने में सक्षम होते हैं।

जब कॉलबैक वापस आता है, #_=_तो इसका अर्थ है कि पृष्ठ को छोड़ने से पहले इसकी मूल स्थिति में था। क्योंकि यह एंकर ब्राउज़र द्वारा पार्स किया जाता है, आपको इसके बारे में चिंता करने की आवश्यकता नहीं है।


2
यदि आपके पास एक रीढ़ की हड्डी का फ्रेमवर्क है जैसे कि बैकबोन या एम्बर तो यह एक मुद्दा है क्योंकि राउटर द्वारा हैश की व्याख्या के बाद सब कुछ है
रुडी

1
URL टुकड़ा पहचानकर्ता ("एंकर") एक अनुरोध पर ब्राउज़र को नहीं भेजे जाते हैं। इसके अलावा, यह सवाल OAuth के बारे में है, न कि मुख्य डेस्कटॉप साइट के बारे में। इसका कारण OAuth सुरक्षा है - एक दुर्भावनापूर्ण रीडायरेक्ट URI को क्राफ्ट करने के कारण हमलों को रोकना।
एंड्रयू

8

मेजर कष्टप्रद, विशेष रूप से उन ऐप्स के लिए जो यूआरआई को पार्स करते हैं और न केवल $ _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>

किसी भी डेटा को पार्स करते समय मान्यताओं के बारे में सावधान रहें जो आप नहीं बनाते हैं। URI टुकड़ा पहचानकर्ता RFC 1738 (1994 में) के रूप में पहले से ही निर्दिष्ट थे, इसलिए यदि आप एक सही URI पार्सर का उपयोग करते हैं, तो यह कभी भी समस्या नहीं होनी चाहिए।
एंड्रयूएफ

6

यदि आप हैशबैंग (/ #! /) URL, जैसे कोणीय के साथ JS फ्रेमवर्क का उपयोग कर रहे हैं, तो यह एक गंभीर समस्या बन सकती है। वास्तव में, कोणीय गैर-हैशबैंग टुकड़े वाले URL को अमान्य मानकर एक त्रुटि देगा:

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

यदि आप ऐसा करने के बजाय ऐसे मामले में हैं (और अपने डोमेन रूट पर पुनर्निर्देशित कर रहे हैं):

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

बस करो:

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

1.2+, यह कमाल का काम करता है। 1.0 और नीचे उपयोग के लिए window.location.hash = '';
प्रदीप महादेव

1
हां, मैंने केवल 1.2 पर इसका परीक्षण किया, विनिर्देश के लिए धन्यवाद!
नीमजी

और फिर
html

5

मैं नहीं देखता कि यह समस्या फेसबुक AJAX से कैसे संबंधित है। वास्तव में समस्या जावास्क्रिप्ट अक्षम और विशुद्ध रूप से पुनर्निर्देशित आधारित लॉगिन के साथ भी होती है।

फेसबुक के साथ एक उदाहरण विनिमय:

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

मेरे लिए भी फ़ायरफ़ॉक्स के साथ ही होता है।


4

इसे मेरे रीडायरेक्ट पृष्ठ पर जोड़ने से मेरे लिए समस्या ठीक हो गई ...

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

1
यह एक खिड़की स्थान परिवर्तन का कारण बनता है, एक पृष्ठ ताज़ा करने की शुरुआत
rpearce

3

कोणीय और कोणीय यूआई रूटर के साथ, आप इसे ठीक कर सकते हैं

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

यहां काम नहीं करता है - नियम लागू होने से पहले मार्ग बदल जाता है (लागू होता है)
Maison Nison

3

यदि आप वी-राउटर का उपयोग कर रहे हैं, तो आप मार्गों की सूची में संलग्न कर सकते हैं:

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

2

हाल ही में एक बदलाव पेश किया गया था कि कैसे फेसबुक सत्र को पुनर्निर्देशित करता है। घोषणा के लिए इस सप्ताह के ऑपरेशन डेवलपर लव ब्लॉग पोस्ट में "सत्र में अनुप्रेषित व्यवहार में बदलाव" देखें ।


1
मुझे यकीन नहीं है, वह यहाँ क्या बात कर रहा है
user210504

2

मेरे लिए, मैं छुटकारा पाने के लिए दूसरे पृष्ठ पर जावास्क्रिप्ट पुनर्निर्देशन करता हूं #_=_। नीचे दिए गए विचार काम करने चाहिए। :)

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

यह एक अच्छा विचार नहीं है क्योंकि मुझे लगता है कि आप कई बेकार अनुरोध बना रहे हैं
Jacek Pietal

1

एक वर्कअराउंड जो मेरे लिए काम करता था (Backbone.js का उपयोग करके), फेसबुक पर पारित रीडायरेक्ट URL के अंत में "# /" जोड़ना था। फेसबुक प्रदान किए गए टुकड़े को रखेगा, और अपने स्वयं के "_ = _" को नहीं जोड़ेगा।

वापस आने पर, बैकबोन "# /" भाग को हटा देगा। AngularJS के लिए, "#!" वापसी URL के लिए काम करना चाहिए।

ध्यान दें कि मूल URL का टुकड़ा पहचानकर्ता पुनर्निर्देशन पर (HTTP स्थिति कोड 300, 301, 302 और 303 के माध्यम से) अधिकांश ब्राउज़रों द्वारा संरक्षित किया जाता है, जब तक कि पुनर्निर्देशित URL में एक टुकड़ा पहचानकर्ता भी नहीं होता है। यह अनुशंसित व्यवहार प्रतीत होता है

यदि आप एक हैंडलर स्क्रिप्ट का उपयोग करते हैं, जो उपयोगकर्ता को कहीं और रीडायरेक्ट करता है, तो आप "#" को यहां पर रीडायरेक्ट URL में एक खाली स्ट्रिंग के साथ खंड पहचानकर्ता को बदलने के लिए जोड़ सकते हैं।


1

मुझे पता है कि यह उत्तर देर से है, लेकिन यदि आप पासपोर्ट का उपयोग कर रहे हैं, तो आप इसे देखना चाहते हैं।

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

मैंने इस मिडलवेयर को लिखा है और सर्वर इंस्टेंस को व्यक्त करने के लिए इसे लागू किया है, और जो मूल URL मुझे मिला है वह बिना है "#_=_"। ऐसा लगता है जब हम passporJS के उदाहरण को सर्वर के उदाहरण के लिए मिडलवेयर के रूप में लागू करते हैं, यह उन वर्णों को नहीं लेता है, लेकिन केवल हमारे ब्राउज़र के एड्रेस बार पर दिखाई देते हैं।


3
"" # = = _ "यह केवल क्लाइंट पर उपलब्ध है। समीक्षा करें: en.wikipedia.org/wiki/Fragment_identifier
alditis

1

मैं इस का उपयोग करता हूं, साथ ही '#' प्रतीक को हटाने के लिए।

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

0

कोणीय 2 (RC5) और हैश-आधारित मार्गों का उपयोग करते हुए, मैं यह करता हूं:

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

तथा

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

जहां तक ​​मैं समझता हूं, =मार्ग में वर्ण को वैकल्पिक मार्ग पैरामीटर परिभाषा के भाग के रूप में व्याख्या किया गया है ( https://angular.io/docs/ts/latest/guide/router.html# !# optional-route-parameters देखें ) , इसलिए मार्ग मिलान में शामिल नहीं हैं।


0

PHP एसडीके उपयोगकर्ताओं के लिए

मैंने आगे बढ़ने से पहले अतिरिक्त हिस्से को हटाकर समस्या को ठीक कर दिया।

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

0

यह आपके url में जोड़े गए वर्णों को हटा देगा

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

0

"# _ = _" (PHP) निकालने का सबसे आसान और साफ उपाय:

इसके बजाय "हैडर (" स्थान: xxx.php ");" "इको (" location.href = 'xxx.php'? ") का उपयोग करने के लिए?"

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.