最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Angular routing doesn't work when URL is directly visited in browser but works when clicked to? - Stack Ove

programmeradmin3浏览0评论

I have an angular app with a directory structure

app 
..views
....partials
......main.jade
......foo.jade
....index.jade

and routes defined like:

'use strict';

angular.module('myApp', [
  'ngCookies',
  'ngResource',
  'ngSanitize',
  'ngRoute', 
  'firebase', 
  'myApp.config'
])
  .config(function ($routeProvider, $locationProvider) {
    $locationProvider.html5Mode(true);  

    $routeProvider
      .when('/', {
        templateUrl: '/partials/main',
        controller: 'MainCtrl'
      })
      .when('/foo/:fooName', {
        templateUrl: '/partials/foo',
        controller: 'FooCtrl'
      })            
      .otherwise({
        redirectTo: '/'
      });
  });

I'm using express on the server side and the relevant code is:

    // server.js 
   app.configure('development', function(){
     app.use(express.static(path.join(__dirname, '.tmp')));
     app.use(express.static(path.join(__dirname, 'app')));
     app.use(express.errorHandler());
   });

   app.configure('production', function(){
    app.use(express.favicon(path.join(__dirname, 'public/favicon.ico')));
    app.use(express.static(path.join(__dirname, 'public')));
   });

    app.get('/', routes.index);
    app.get('/partials/:name', routes.partials);

    //routes.js
    exports.index = function(req, res){
      res.render('index');
    };


    exports.partials = function(req, res){
      var name = req.params.name;
      res.render('partials/' + name);
    };

The main route "/" loads fine and when i click to "/foo/bar" the partial view foo.jade loads as expected. However, when I try visiting "/foo/bar" directly in the URL i get a 404 response from Express "cannot GET /foo/bar" which makes sense since there's no route like this defined in express. However, I thought this was the whole point of defining the angular router..i.e. it's supposed to intercept this request and actually ask for "/partials/foo". I tried adding

//redirect all others to the index (HTML5 history)
app.get('*', routes.index);

but it didnt solve the issue and seemed to be catching even the requests for static js assets and responding with the contents of index.html which is pretty bad. I'm sure I'm doing something wrong. How can I fix things so that I can directly visit the URLs?

I have an angular app with a directory structure

app 
..views
....partials
......main.jade
......foo.jade
....index.jade

and routes defined like:

'use strict';

angular.module('myApp', [
  'ngCookies',
  'ngResource',
  'ngSanitize',
  'ngRoute', 
  'firebase', 
  'myApp.config'
])
  .config(function ($routeProvider, $locationProvider) {
    $locationProvider.html5Mode(true);  

    $routeProvider
      .when('/', {
        templateUrl: '/partials/main',
        controller: 'MainCtrl'
      })
      .when('/foo/:fooName', {
        templateUrl: '/partials/foo',
        controller: 'FooCtrl'
      })            
      .otherwise({
        redirectTo: '/'
      });
  });

I'm using express on the server side and the relevant code is:

    // server.js 
   app.configure('development', function(){
     app.use(express.static(path.join(__dirname, '.tmp')));
     app.use(express.static(path.join(__dirname, 'app')));
     app.use(express.errorHandler());
   });

   app.configure('production', function(){
    app.use(express.favicon(path.join(__dirname, 'public/favicon.ico')));
    app.use(express.static(path.join(__dirname, 'public')));
   });

    app.get('/', routes.index);
    app.get('/partials/:name', routes.partials);

    //routes.js
    exports.index = function(req, res){
      res.render('index');
    };


    exports.partials = function(req, res){
      var name = req.params.name;
      res.render('partials/' + name);
    };

The main route "/" loads fine and when i click to "/foo/bar" the partial view foo.jade loads as expected. However, when I try visiting "/foo/bar" directly in the URL i get a 404 response from Express "cannot GET /foo/bar" which makes sense since there's no route like this defined in express. However, I thought this was the whole point of defining the angular router..i.e. it's supposed to intercept this request and actually ask for "/partials/foo". I tried adding

//redirect all others to the index (HTML5 history)
app.get('*', routes.index);

but it didnt solve the issue and seemed to be catching even the requests for static js assets and responding with the contents of index.html which is pretty bad. I'm sure I'm doing something wrong. How can I fix things so that I can directly visit the URLs?

Share Improve this question asked Dec 8, 2013 at 21:03 algorithmicCoderalgorithmicCoder 6,78921 gold badges75 silver badges118 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 18

The reason routing is behaving like this is html5mode turned on. Notice the line: $locationProvider.html5Mode(true);

You need to understand that when you try to access "/foo/bar" directly your browser sends HTTP GET request to this URL. When you try to access this url via link clicking, like you said, Angular is intercepting this action and calls History.pushState that only updates browser's link.

What you need to do in order to make html5mode routing work is implementing url rewrite. Every request has to be redirected to your index file that bootstraps AngularJS application, but this needs to be done on your server. Angular will render the desired page by itself.

Check out connect mod rewrite grunt task that does exacly that.

You can also you this middleware directly.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论