• Angular1.0路由的Hashbang和HTML5模式


    原文答主jupiter

    http://stackoverflow.com/questions/16677528/location-switching-between-html5-and-hashbang-mode-link-rewritingdown vote

    The documentation is not very clear about AngularJS routing. It talks about Hashbang and HTML5 mode. In fact, AngularJS routing operates in three modes:

    1. Hashbang Mode
    2. HTML5 Mode
    3. Hashbang in HTML5 Mode

    For each mode there is a a respective LocationUrl class (LocationHashbangUrl, LocationUrl and LocationHashbangInHTML5Url).

    In order to simulate URL rewriting you must actually set html5mode to true and decorate the $sniffer class as follows:

    $provide.decorator('$sniffer', function($delegate) {
    $delegate.history = false;
      return $delegate;
    });

    I will now explain this in more detail:

    Hashbang Mode

    Configuration:

    $routeProvider
    .when('/path', {
    templateUrl: 'path.html',
    });
    $locationProvider
    .html5Mode(false)
    .hashPrefix('!');


    This is the case when you need to use URLs with hashes in your HTML files such as in

    <a href="index.html#!/path">link</a>
    In the Browser you must use the following Link: http://www.example.com/base/index.html#!/base/path

    As you can see in pure Hashbang mode all links in the HTML files must begin with the base such as "index.html#!".

    HTML5 Mode

    Configuration:

    $routeProvider
    .when('/path', {
    templateUrl: 'path.html',
    });
    $locationProvider
    .html5Mode(true);


    You should set the base in HTML-file

    <html>
    <head>
    <base href="/">
    </head>
    </html>


    In this mode you can use links without the # in HTML files

    <a href="/path">link</a>
    Link in Browser:

    http://www.example.com/base/path
    Hashbang in HTML5 Mode

    This mode is activated when we actually use HTML5 mode but in an incompatible browser. We can simulate this mode in a compatible browser by decorating the $sniffer service and setting history to false.

    Configuration:

    $provide.decorator('$sniffer', function($delegate) {
    $delegate.history = false;
    return $delegate;
    });
    $routeProvider
    .when('/path', {
    templateUrl: 'path.html',
    });
    $locationProvider
    .html5Mode(true)
    .hashPrefix('!');


    Set the base in HTML-file:

    <html>
    <head>
    <base href="/">
    </head>
    </html>


    In this case the links can also be written without the hash in the HTML file

    <a href="/path">link</a>


    Link in Browser:

    http://www.example.com/index.html#!/base/path

    使用最后一种, html内用{{linkPrefix}} 等于'/', 结果自动在/后面加上!#并且能回退自如,直接访问地址栏

    (function () {
    
      'use strict';
    
      var appConfig = function ($routeProvider, jwtInterceptorProvider, $httpProvider, $locationProvider,$provide) {
        $routeProvider.otherwise('/404');
    
        //jwtInterceptorProvider.tokenGetter = function (store) {
        //  return store.get('jwt');
    
    //可以使用多个decorator
              $provide.decorator('$locale', function ($delegate) {
                  var value = $delegate.DATETIME_FORMATS;
    
                  value.SHORTDAY = [
                      "",
                      "",
                      "",
                      "",
                      "",
                      "",
                      ""
                  ];
    
                  return $delegate;
              });
    //装饰sniffer
              $provide.decorator('$sniffer', function($delegate) {
              $delegate.history = false;
                return $delegate;
              });
    
    
        $httpProvider.interceptors.push('jwtInterceptor');
        $httpProvider.interceptors.push('TokenInterceptor');
    
    
    
    
          $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
    
    
          $locationProvider.html5Mode({ enabled: true, requireBase: false, rewriteLinks: true }); 
          $locationProvider.hashPrefix('!');  
        };
    
      appConfig.$inject = ['$routeProvider', 'jwtInterceptorProvider', '$httpProvider', '$locationProvider','$provide'];
    
      var appRun = function ($rootScope,$window, $location, jwtHelper,$translate, AuthService, $sessionStorage,deviceDetector) {
    
          $rootScope.isMobile="is_mobile";
          $rootScope.screenWidth=$window.innerWidth;
          if  ((deviceDetector.os==="android"||deviceDetector.os==="ios" ||deviceDetector.os==="windows-phone"||deviceDetector.device==="blackberry")&& $rootScope.screenWidth<768)
              $rootScope.isMobile=true;
            else $rootScope.isMobile=false;
    
    
        // Store user data in $rootScope.account if user is logged in
        if ($sessionStorage.jwt && !jwtHelper.isTokenExpired($sessionStorage.jwt)) {
          var jwt = $sessionStorage.jwt;
          $rootScope.account = jwt && jwtHelper.decodeToken(jwt);
    
        }
    
    
    
        $rootScope.$on('$routeChangeStart', function (e, to) {
          if (to.data) {
            if (to.data.requiresLogin) {
              // Stop users from getting to routes that have value requiresLogin set on true
              if (!$sessionStorage.jwt || jwtHelper.isTokenExpired($sessionStorage.jwt)) {
                e.preventDefault();
                  $translate("Token Expired.").then(function(value){
    
                          $rootScope.tokenExpired=value;
                          $window.alert($rootScope.tokenExpired);
                      }
                  );
    
    
                $location.path('/');
              }
            } else {
              // Stop users from getting to routes that have value requiresLogin set on false
              if ($sessionStorage.jwt && !jwtHelper.isTokenExpired($sessionStorage.jwt)) {
                e.preventDefault();
                $location.path(AuthService.getLoginRedirectUrl());
              }
            }
          }
        });
    
    
    
      };
    
      appRun.$inject = ['$rootScope', '$window','$location', 'jwtHelper','$translate', 'AuthService', '$sessionStorage','deviceDetector'];
    
      angular
        .module('warrantyProcessApp', [
          'ngRoute',
          ... ...
    
        ])
        .config(appConfig)
        .run(appRun);
    
    })();
    例子

     不过我得到的路径是http://www.example.com/#!/base/path

    访问根目录是http://www.example.com/#!/ ( 后面的/#!/都是访问时自动rewirte 到地址栏的 )

    twitter和17startup的地址url中都有#!,被称为pretty ajax url 
     
     
    如果说是地址重写或者是restful风格为什么要用#!这么奇怪的地址呢?
    以下内容截取自顾轶灵的回答:

    传统jQuery方法:

    利用 HTML5 history session management 作为历史记录:

    This way you don't have to use hashes in newer browsers and that way the user won't notice a thing.

    function route(path) {
        $.get(path, function(data) {
            //parse data
        });
    }
    
    if (typeof history.pushState !== 'undefined') 
    {
        $(window).bind('popstate', function(e)
        {
            route(window.location.pathname);
        });
        $('a').click(function(event) {
            event.preventDefault();
            history.pushState({},'',this.href);
        });
    } else {
        $(window).bind('hashchange', function(e)
        {
            route(window.location.hash);
        });
        $('a').click(function(event) {
            event.preventDefault();
            $(this).attr('href', '/#'+$(this).attr('href'));
        });
    }

     延伸阅读:

    angular 路由去除#号

    http://www.cnblogs.com/breakdown/p/3785773.html

  • 相关阅读:
    Influx Sql系列教程一:database 数据库
    Influx Sql系列教程零:安装及influx-cli使用姿势介绍
    移动端/H5关于cursor:pointer导致的问题
    onselectstart="return false"
    js正则验证之不能使用相同字符
    js通过sessionStorage实现的返回上一页
    MetaHandler.js:移动端适配各种屏幕
    iOS下的 Fixed + Input 调用键盘的时候fixed无效问题解决方案
    js判断三个数字中的最大值
    js判断微信浏览器
  • 原文地址:https://www.cnblogs.com/haimingpro/p/6399748.html
Copyright © 2020-2023  润新知