Reloading the page gives wrong GET request with AngularJS HTML5 mode

I want to enable HTML5 mode for my app. I have put the following code for the configuration, as shown here:

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

    $locationProvider.html5Mode(true);
    $locationProvider.hashPrefix = '!';

    $routeProvider.when('/', {
        templateUrl: '/views/index.html',
        controller: 'indexCtrl'
    });
    $routeProvider.when('/about',{
        templateUrl: '/views/about.html',
        controller: 'AboutCtrl'
    });

As you can see, I used the $locationProvider.html5mode and I changed all my links at the ng-ref to exclude the /#/ .

The Problem

At the moment, I can go to localhost:9000/ and see the index page and navigate to the other pages like localhost:9000/about .

However, the problem occurs when I refresh the localhost:9000/about page. I get the following output: Cannot GET /about

If I look at the network calls:

Request URL:localhost:9000/about
Request Method:GET

While if I first go to localhost:9000/ and then click on a button that navigates to /about I get:

Request URL:http://localhost:9000/views/about.html

Which renders the page perfectly.

How can I enable angular to get the correct page when I refresh?


From the angular docs

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

The reason for this is that when you first visit the page ( /about ), eg after a refresh, the browser has no way of knowing that this isn't a real URL, so it goes ahead and loads it. However if you have loaded up the root page first, and all the javascript code, then when you navigate to /about Angular can get in there before the browser tries to hit the server and handle it accordingly


There are few things to set up so your link in the browser will look like http://yourdomain.com/path and these are your angular config + server side

1) AngularJS

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

2) server side, just put .htaccess inside your root folder and paste this

RewriteEngine On 
Options FollowSymLinks

RewriteBase /

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /#/$1 [L]

More interesting stuff to read about html5 mode in angularjs and the configuration required per different environment https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-your-server-to-work-with-html5mode Also this question might help you $location / switching between html5 and hashbang mode / link rewriting


I had a similar problem and I solved it by:

  • Using <base href="/index.html"> in the index page

  • Using a catch all route middleware in my node/Express server as follows (put it after the router):

  • app.use(function(req, res) {
        res.sendfile(__dirname + '/Public/index.html');
    });
    

    I think that should get you up and running.

    If you use an apache server, you might want to mod_rewrite your links. It is not difficult to do. Just a few changes in the config files.

    All that is assuming you have html5mode enabled on angularjs. Now. note that in angular 1.2, declaring a base url is not recommended anymore actually.

    链接地址: http://www.djcxy.com/p/68988.html

    上一篇: IE8问题与Twitter Bootstrap 3

    下一篇: 重新加载页面给AngularJS HTML5模式提供了错误的GET请求