首页 文章

Facebook Callback将'#_=_'附加到Return URL

提问于
浏览
435

Facebook回调已开始将 #_=_ 哈希下划线附加到返回URL

有谁知道为什么?解决办法是什么?

21 回答

  • 4

    我知道这个回复很晚,但是如果你使用的是passportjs,你可能想看看这个 .

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

    我编写了这个中间件并将其应用于表达服务器实例,我得到的原始URL没有 "#_=_" . 当我们应用passporJS ' instance as middleware to the server instance, it doesn' t取这些字符时看起来像这样,但只能在我们浏览器的地址栏上看到 .

  • 1

    将此添加到我的重定向页面为我解决了问题...

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

    如果您使用带有hashbang(/#!/)URL的JS框架,例如,这可能会成为一个严重的问题 . 角 . 实际上,Angular会将带有非hashbang片段的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
    
  • 57

    您还可以在 redirect_uri 参数上为Facebook回调指定自己的哈希值,这在某些情况下可能会有所帮助,例如: /api/account/callback#home . 当你被重定向回来时,如果你使用的是backbone.js或类似的(不确定jquery mobile),它至少会是一个与已知路由相对应的哈希值 .

  • 6

    如果你想从网址中删除剩余的“#”

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

    我用这个,删除'#'符号 .

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

    TL;DR

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

    Full version with step by step instructions

    // 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 = '';
    
        }
    
    }
    

    一步步:

    • 如果 fragment#_=_ ,我们只会进入代码块 .

    • 检查浏览器是否支持HTML5 window.replaceState方法 .

    • 通过拆分 # 并仅采用第一部分来清理URL .

    • 告诉 history 用干净的URL替换当前页面状态 . 这会修改当前历史记录条目,而不是创建新条目 . 这意味着后退和前进按钮将按照您想要的方式工作 . ;-)

    • 如果浏览器不支持令人敬畏的HTML 5历史记录方法,那么只需将哈希设置为空字符串即可尽可能地清理URL . 这是一个糟糕的回退,因为它仍然留下一个尾随哈希值(example.com/#)并且它还添加了一个历史记录条目,因此后退按钮会将您带回 #_-_ .

    了解有关history.replaceState的更多信息 .

    了解有关window.location的更多信息 .

  • 10

    使用Angular 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),因此不参与路由匹配 .

  • 8

    For PHP SDK users

    我只是通过在转发之前删除额外部分来解决问题 .

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

    我不知道这个问题是如何与facebook AJAX相关的 . 实际上,在禁用JavaScript和纯粹基于重定向的登录时也会出现此问题 .

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

    我也只能使用Firefox .

  • 9

    对我有用的解决方法(使用Backbone.js)是将“#/”添加到传递给Facebook的重定向URL的末尾 . Facebook将保留提供的片段,而不是附加自己的“_ = _” .

    返回后,Backbone将删除“#/”部分 . 对于AngularJS,附加“#!”到返回URL应该工作 .

    请注意,大多数浏览器在重定向(通过HTTP状态代码300,301,302和303)时保留原始URL的片段标识符,除非重定向URL也具有片段标识符 . 这seems to be recommended behaviour .

    如果使用将用户重定向到其他位置的处理程序脚本,则可以在此处向重定向URL附加“#”,以使用空字符串替换片段标识符 .

  • 95

    主要烦人,特别是对于解析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>
    
  • 1

    Facebook使用框架,在其中使用AJAX通信的所有功能 . 这种情况下最大的问题是保留当前页面状态 . 据我所知,Facebook决定使用模拟锚点 . 这意味着如果您在某处单击,它们会将其模拟为页面内的锚点,并且当AJAX通信开始时,它们也会更改URL的锚点位 .

    当您尝试重新加载页面时,此解决方案通常可以帮助您(不是ENTER,按F5),因为您的浏览器会将带有锚点的整个URL发送到Facebook服务器 . 因此,Facebook会选择最新状态(您所看到的),然后您可以从那里继续 .

    When the callback returns with #= it means that the page was in its basic state prior to leaving it. Because this anchor is parsed by the browser, you need not worry about it.

  • 0

    这会将附加的字符移除到您的网址

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

    如果您正在使用vue-router,则可以附加到路由列表:

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

    使用角度和角度ui路由器,您可以解决此问题

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

    最近,Facebook处理会话重定向的方式发生了变化 . 请参阅本周Operation Developer Love博客文章中的"Change in Session Redirect Behavior"以了解公告 .

  • 8

    通过Facebook's Platform Updates

    改变会话重定向行为本周,当此字段留空时,我们开始向redirect_uri添加片段#____ = ____ . 请确保您的应用可以处理此行为 .

    要防止这种情况,请在您的登录URL请求中设置redirect_uri,如下所示:(使用Facebook php-sdk)

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

    UPDATE

    以上就像documentation所说的解决这个问题 . 但是,Facebook的文档化解决方案不起作用 . 请考虑在Facebook Platform Updates blog post上发表评论,然后按照this bug获得更好的答案 . 在此之前,将以下内容添加到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>
    
  • 0

    出于安全原因,这是由Facebook设计实现的 . 以下是Facebook团队成员Eric Osgood的解释:

    这被标记为“按设计”,因为它可以防止潜在的安全漏洞 . 某些浏览器会将URL中的哈希片段附加到已重定向到的新URL的末尾(如果新URL本身没有哈希片段) . 例如,如果example1.com返回到example2.com的重定向,那么访问example1.com#abc的浏览器将转到example2.com#abc,而example1.com上的散列片段内容可以访问example2上的脚本.COM . 由于可以将一个auth流重定向到另一个,因此可以从一个应用程序访问另一个应用程序的敏感身份验证数据 . 通过将新的哈希片段附加到重定向URL来缓解此问题,以防止此浏览器行为 . 如果关注结果URL的美学或客户端行为,则可以使用window.location.hash(甚至是您自己的服务器端重定向)来删除有问题的字符 .

    资料来源:https://developers.facebook.com/bugs/318390728250352/

  • 229

    不确定为什么他们这样做但是,你可以通过重置页面顶部的哈希来解决这个问题:

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

    对我来说,我将JavaScript重定向到另一个页面以摆脱 #_=_ . 以下想法应该有效 . :)

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

相关问题