Facebook回调已经开始追加#_=_哈希下划线返回URL

有人知道为什么吗?解决方案是什么?


当前回答

如果您想从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
  }
})

其他回答

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

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

主要恼人的,特别是应用程序解析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>

使用Angular 2 (RC5)和基于哈希的路由,我这样做:

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

and

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

据我所知,路由中的=字符被解释为可选路由参数定义的一部分(见https://angular.io/docs/ts/latest/guide/router.html#!#optional-route-parameters),因此不涉及路由匹配。

这是Facebook出于安全考虑而设计的。下面是Facebook团队成员埃里克·奥斯古德的解释:

This has been marked as 'by design' because it prevents a potential security vulnerability. Some browsers will append the hash fragment from a URL to the end of a new URL to which they have been redirected (if that new URL does not itself have a hash fragment). For example if example1.com returns a redirect to example2.com, then a browser going to example1.com#abc will go to example2.com#abc, and the hash fragment content from example1.com would be accessible to a script on example2.com. Since it is possible to have one auth flow redirect to another, it would be possible to have sensitive auth data from one app accessible to another. This is mitigated by appending a new hash fragment to the redirect URL to prevent this browser behavior. If the aesthetics, or client-side behavior, of the resulting URL are of concern, it would be possible to use window.location.hash (or even a server-side redirect of your own) to remove the offending characters.

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

使用angular和angular ui router,你可以修复这个问题

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