【问题标题】:AngularJS: can't get html5 mode urls with ui-route $stateAngularJS:无法使用 ui-route $state 获取 html5 模式网址
【发布时间】:2013-06-30 21:52:55
【问题描述】:

我正在使用ui-router 进行状态管理,但我认为我的 .htaccess 重写规则有问题。使用 /#/account 样式网址时,我所有的状态都有效。现在我启用了 html5 模式,但我的应用程序没有像以前那样呈现。它似乎加载了我的 index.html 以及我所有的 js 和 css 文件等,但实际上并没有初始化任何状态。

这是我的文件夹结构:

root/
    app/
        components/
            angular/
            ...
        images/
        scripts/ 
            controllers/
            directives/
            ...
            app.js       
        styles/
        views/
        .htaccess
        ...

我的虚拟主机 DocumentRoot 指向我的app/

这是我的 app.js 和我的状态:

'use strict';

angular.module('appointeddPortalApp',  ['ngResource', 'ui.state', 'ui.compat', 'fundoo.services', 'ui.date', 'ngCookies'])
.config(function ($stateProvider, $routeProvider, $locationProvider, $httpProvider) {

    var access = routingConfig.accessLevels;

    delete $httpProvider.defaults.headers.common["X-Requested-With"];
    $httpProvider.defaults.useXDomain = true;
    $locationProvider.html5Mode(true);

    $stateProvider
    .state('root', {
        abstract: true,
        url: '',
        views: {
            'header': {
                templateUrl: 'views/partials/header.html'
            },
            'search': {
                templateUrl: 'views/partials/search.html',
                controller: 'SearchCtrl'
            },
            'main': {
                templateUrl: 'views/main.html',
                controller: 'MainCtrl'
            },
            'footer': {
                templateUrl: 'views/partials/footer.html'
            },
        },
    })
    .state('root.home', {
        url: '',
        views: {
            'content': {
                templateUrl: 'views/home/index.html',
                controller: 'MainCtrl',
            }
        },
        access: access.anon
    })
    .state('root.about', {
        url: '/about',
        parent: 'root',
        views: {
            'content': {
                templateUrl: 'views/about.html',
                controller: 'StaticCtrl'
            },
            'search@': {}
        },
        access: access.anon
    })
    .state('root.search', {
        url: '/search/:city/:category',
        views: {
            'content': {
                templateUrl: 'views/search.html',
                controller: 'SearchCtrl'
            }
        },
        access: access.anon
    })
    .state('root.salons_profile', {
        url: '/salons/{id}',
        views: {
            'content': {
                templateUrl: 'views/salons.profile.html',
                controller: 'SalonCtrl',
            },
            'search@': {}
        },
        access: access.anon
    })
    .state('root.account', {
        url: '/account',
        abstract: true,
        views: {
            'content': {
                templateUrl: 'views/user/account.html',
                controller: 'AccountCtrl'
            }
        },
    })
    .state('root.account.info', {
        url: '',
        views: {
            'account_head': {
                templateUrl: 'views/user/account.head.html',
            },
            'account_body': {
                templateUrl: 'views/user/account.my_appointedd.html',
            },
        },
        menus: {
            'account': {
                identifier: 'my_appointedd',
                class: 'active'
            }
        },
        access: access.user
    })
    .state('root.account.appointments', {
        url: '/appointments',
        views: {
            'account_head': {
                templateUrl: 'views/user/account.head.html',
            },
            'account_body': {
                templateUrl: 'views/user/account.appointments.html',
            },
        },
        menus: {
            'account': {
                identifier: 'appointments',
                class: 'active'
            }
        },
        access: access.user
    })
    .state('root.account.details', {
        abstract: true,
        views: {
            'account_head': {
                templateUrl: 'views/user/account.head.html',
            },
            'account_body': {
                templateUrl: 'views/user/account.details.html',
            },
        },
        access: access.user
    })
    .state('root.account.details.account', {
        url: '/details',
        views: {
            'right': {
                templateUrl: 'views/user/account.details.account.html',
            },
        },
        menus: {
            'account': {
                identifier: 'details',
                class: 'active'
            },
            'settings': {
                identifier: 'account',
                class: 'active'
            }
        },
        access: access.user
    })
    .state('root.account.details.profile', {
        url: '/profile',
        views: {
            'right': {
                templateUrl: 'views/user/account.details.profile.html',
            },
        },
        menus: {
            'account': {
                identifier: 'details',
                class: 'active'
            },
            'settings': {
                identifier: 'profile',
                class: 'active'
            }
        },
        access: access.user
    });


})
.run( [ '$location', '$state', '$stateParams', '$rootScope', '$cookies', 'Auth', function( $location, $state, $stateParams, $rootScope, $cookies, Auth){

    $rootScope.client_id = '51a741eb3152c3ae7e000103';
    $rootScope.$state = $state;
    $rootScope.$stateParams = $stateParams;
    $rootScope.$cookies = $cookies;

    $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){
        if (!Auth.authorize(toState.access)) {
            if(Auth.isLoggedIn()) $state.transitionTo('root.account');
            else                  $state.transitionTo('root.home');
        }
    });

这是我的重写代码,它位于 /app 的 .htaccess 中。我认为这可能是错误的。

<IfModule mod_rewrite.c>
  Options +FollowSymLinks 
  RewriteEngine On 
  RewriteBase / 
  RewriteRule ^(components|images|scripts|styles|views)($|/) - [L]
  RewriteRule ^(.*)$ index.html [L]
</IfModule>

【问题讨论】:

    标签: javascript angularjs .htaccess url-routing


    【解决方案1】:

    如果在不允许编辑 Apache 配置的共享主机中工作,您可以在 .htaccess 文件中进行设置,以使 $locationProvider.html5Mode(true) 工作(正如 @Shanimal 在 @nfiniteloop 答案中指出的那样):

    RewriteEngine on
    
    RewriteBase /path/to/app #change this!
    
    # Don't rewrite files or directories
    RewriteCond %{REQUEST_FILENAME} -f [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^ - [L]
    
    # Rewrite everything else to index.html to allow html5 state links
    RewriteRule ^ index.html [L]
    

    别忘了在 HTML 中添加&lt;base href="/path/to/app/"&gt; &lt;head&gt;。

    【讨论】:

      【解决方案2】:

      我们的许多使用 html5mode 和 ui-router 的 Apache 用户都可以使用此配置。

      <VirtualHost *:80>
          ServerName my-app
      
          DocumentRoot /path/to/app
      
          <Directory /path/to/app>
              RewriteEngine on
      
              # Don't rewrite files or directories
              RewriteCond %{REQUEST_FILENAME} -f [OR]
              RewriteCond %{REQUEST_FILENAME} -d
              RewriteRule ^ - [L]
      
              # Rewrite everything else to index.html to allow html5 state links
              RewriteRule ^ index.html [L]
          </Directory>
      </VirtualHost>
      

      另外请确保您不是&lt;base href&gt; 错误的受害者。请参阅ui-router FAQ 了解更多信息。

      【讨论】:

      • 嗨,nfiniteloop,看来我的问题是 错误!谢谢!
      • 你摇滚。 +1。菜鸟...您可以将 &lt;Directory 节点内的所有内容放到根目录下的 .htaccess 中,您的网络主机也会产生相同的效果。干杯!
      • 在drupal中当我设置这个规则时将如何设置500内部服务器错误请帮助
      • 但是不是每条路线都丢失了,我总是被重定向到家吗?例如。 mypage.de/abc 将被重定向到 mypage.de/index.html 而不是 mypage.de/#/abc
      • 这似乎不适用于子状态“admin.classes”。我得到一个 404 未找到。我确实将此规则添加到我的 htaccess 文件中:RewriteRule ^admin/(.*)$ /$1 [R,L]。当我在 /admin/classes 上重新加载页面时。我被路由到 /classes。
      猜你喜欢
      • 2017-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-18
      • 2020-12-07
      • 1970-01-01
      相关资源
      最近更新 更多