Angular Js Lazy loading and html5mode

683 Views Asked by At

So I'm currently messing around with using LazyLoading in angularJS with AngularAMD, Require.js, and Angular-Route, and I keep running into an error when html5Mode is enabled. When html5Mode is off, everything works fine. However, if its on, the route will change and work the first time, but if you refresh the page it will give a 404 error.

For Example, if I'm at (html5ModeOn):

http://localhost/Lazy_Loading/

It will show the normal H1 and the two links. If i click the link to go to page two, it will change the url, and update the page. At this point, if I refresh, the page goes blank, and the console says:

"NetworkError: 404 Not Found - http://localhost/Lazy_Loading/page2"

If I turn html5Mod off, and do the same thing, (only with /#/ in the url obviously), everything works fine. Any ideas?

Index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Angular Lazy Loading</title>
    <base href="http://localhost/Lazy_Loading/" />
</head>
<body>
    <div ng-view></div>

    <script src="bower_components/requirejs/require.js" data-main="app/config.js"></script>
</body>
</html>

app/config.js

require.config({
    baseUrl:'app',
    paths: {
        'angular': '../bower_components/angular/angular',
        'angular-route': '../bower_components/angular-route/angular-route',
        'angularAMD': '../bower_components/angularAMD/angularAMD'
    },
    shim: {
        'angular': {
            'exports': 'angular'
        },
        'angular-route': ['angular'],
        'angularAMD': ['angular']
    },
    priority: [
        'angular'
    ],
    deps: [
        'app'
    ]
});

app/app.js

define(['angularAMD','angular-route'], function (angularAMD) {
    'use strict';

    var app = angular.module('webapp', ['ngRoute']);

    app.config(['$routeProvider','$locationProvider', function ($routeProvider, $locationProvider) {

        $locationProvider.html5Mode(true);

        $routeProvider.when('/', angularAMD.route({
            templateUrl: 'app/home/home.html',
            controller: 'homeCtrl',
            controllerUrl: 'app/home/homeController.js'
        }))
        // .when('/:client', angularAMD.route({ // This also doesn't work for some reason
        //     templateUrl: 'app/home/home.html',
        //     controller: 'homeCtrl',
        //     controllerUrl: 'app/home/homeController.js',
        //     accessLevel: 0
        // }))
        .when('/page2', angularAMD.route({
            templateUrl: 'app/page2/page2.html',
            controller: 'page2Ctrl',
            controllerUrl: 'app/dashboard/page2Controller.js'
        }))
        .otherwise({redirectTo: "/"});
    }]);

    var appCtrl = app.controller('appCtrl', ['$rootScope','$location', function ($rootScope, $location) {

        $rootScope.$on("$routeChangeStart", function (event, next, current) {
        });

        $rootScope.$on("$routeChangeError", function (event, next, current, rejection) {
        })

        $rootScope.$on("$routeChangeSuccess", function (event, next, current, success) {
        })
    }]);



    angularAMD.bootstrap(app);

    return app;
});

app/home/homeController.js

define(['app'], function (app) {
    app.register.controller('homeCtrl',['$scope', '$routeParams', '$http', function ($scope, $routeParams, $http) {
        console.log("Home Page");
    }]);
});

app/page2/page2Controller.js

define(['app'], function (app) {
    app.register.controller('page2Ctrl',['$scope', '$routeParams', '$http', function ($scope, $routeParams, $http) {
        console.log("Home Page");
    }]);
});

app/home/home.html

<h1>Home Page</h1>
<a href="page2">Page 2</a> <br />
<a href="#page2">#Page 2</a>
1

There are 1 best solutions below

1
On BEST ANSWER

If you refresh the page, the browser will request the url http://localhost/Lazy_Loading/page2 from webserver. On the webserver this url obviously doesn't exist, therefore the 404 error.

It is working without the html5 mode, because you're requesting the "index" page, which is your application, which then processes the route after loading.

The basic solution is to modify your webserver, to always return your "index" page (http://localhost/Lazy_Loading) when requesting a page which is not found on the server. If you can't modify your server, you need to disable html5 mode.