AngularJS Dynamic Routes Without Hashtag

2019-08-05 17:55发布

问题:

I am building an application using Angular and not sure how to handle dynamically created urls that do not contain the #. I have tried the html5Mode true but that doesn't work because the server is looking for the actual directory.

I want to have an informational homepage for the app that appears when you type in domain.com. A user can create a custom page via an admin app that would be available at domain.com/john. My code below works with hashtags but that creates domain.com/#/ and domain.com/#/john.

How do I change my code to work for my desired outcome? When I tried the html5Mode, domain.com/john goes to a 404.

app.js

config(['$routeProvider', function($routeProvider) {
    $routeProvider.when('/', {templateUrl: 'views/home.html', controller: 'HomeCtrl'});
    $routeProvider.when('/:user', {templateUrl: 'views/user.html', controller: 'UserCtrl'});
    $routeProvider.otherwise({redirectTo: '/'});
    //$locationProvider.html5Mode(true);
}]);

controller.js

controller('UserCtrl', ['$scope', '$routeParams', function ($scope, $routeParams) {

    var param = $routeParams.user;

}]);

回答1:

If you arrive at one of those routes from within your app it will work fine, but if you copy and paste that into your browser address bar you'll get a 404 because the server does not understand how to route to those addresses, for example if you try to go to domain.com/john you will get an error because the server is going to look for a john.html page which most likely wont be there. What you could do is configure your server to return to your base page home.html for requests without the # and then angular will handle forwarding you to that route from there.

See the docs on HTML5 routing.

Using this mode requires URL rewriting on server side, basically you have to rewrite all your links to entry point of your application (e.g. index.html)

Another alternative (worse approach compared to server side url rewriting) is to give fully qualified addresses to your resorces in your rout config with respect to the root of the server, for example

var myRoutingApp = angular.module('routingApp', ['ngResource', 'ngRoute', 'kendo.directives', 'ngGrid'])
    .config(function ($routeProvider, $locationProvider) {
        $routeProvider.when('/', { templateUrl: '../Angular/AngularSeed/app/templates/Home.html', controller: '../Angular/AngularSeed/app/controllers/HomeController' });
        $routeProvider.when('/Companies', { templateUrl: '../Angular/AngularSeed/app/templates/Page1.html', controller: '../Angular/AngularSeed/app/controllers/Page1Controller' });
        $routeProvider.when('/CreateCompany', { templateUrl: '../Angular/AngularSeed/app/templates/Page2.html', controller: '../Angular/AngularSeed/app/controllers/Page2Controller' }); ......
        $locationProvider.html5Mode(true);

        $routeProvider.otherwise({ redirectTo: '/' });
    });

That works, but is clearly not ideal.