Angular routing in HTML5mode with Node.js
You might be using the express middleware in the wrong way. Looking at the documentation tells me for example that the following code
.use( '/images', express.static( indexPath + '/images' ) )
Serves any file under the folder indexPath + '/images'
with such URLs:
http://localhost:3000/images/kitten.jpghttp://localhost:3000/images/logo.pnghttp://localhost:3000/images/whatever.jpg
Is that what you would expect it to do?
My suggestion is to change from
.use( '/', require( './routes/home' ) )
to
.use(express.static( indexPath ))
Because according to the documentation, it will serve all static files under the indexPath
folder from the root path, aka. with no prefix.
I think that is all I can help with the input you gave so far. If that doesn't do the trick, maybe you can share some small code example that I can use to reproduce it on my own.
UPDATE
Ok. I've tried to create a simple example of it. I made it work in the following way.My directory structure is like this:
|- index.js|- public/|---- index.html|---- test.html|---- main.js|---- angular.js|---- angular-route.js
index.js
is the node server. Pay attention to the order of the routing. I also added some /home/login
example to make it clear how to add other server routes that should not go through angular.
var http = require('http');var express = require('express');var app = express();app .use(express.static('public')) .get('/home/login', function (req, res) { console.log('Login request'); res.status(200).send('Login from server.'); }) .all('/*', function ( req, res ) { console.log('All'); res .status( 200 ) .set( { 'content-type': 'text/html; charset=utf-8' } ) .sendfile('public/index.html' ); }) .on( 'error', function( error ){ console.log( "Error: \n" + error.message ); console.log( error.stack ); });http .createServer( app ).listen( 8080 ) .on( 'error', function( error ){ console.log( "Error: \n" + error.message ); console.log( error.stack ); });console.log('Serving app on port 8080');
index.html
is pretty simple.
<!doctype html><html><head> <title>Angular HTML5 express test</title> <script type="text/javascript" src="angular.js"></script> <script type="text/javascript" src="angular-route.js"></script> <script type="text/javascript" src="main.js"> </script></head><body ng-app="app"> <div ng-view></div></body></html>
main.html
just adds some content. Important is the link to /test
<div> <h1>This is just a {{val}}</h1> <button ng-click="clicked()">Click me!</button> <span>You clicked {{counter}} times</span> <a href="/test">test me!</a></div>
test.html
is actually irrelevant
<div> <h4>What a beautiful day to test HTML5</h4></div>
main.js
is doing the core angular html5 work
angular.module('app', ['ngRoute']) .config(function($locationProvider) { $locationProvider .html5Mode({ enabled: true, // set HTML5 mode requireBase: false // I removed this to keep it simple, but you can set your own base url }); }) .config(function($routeProvider) { $routeProvider .when('/test', {templateUrl: 'test.html', controller: function() { console.log('On /test.'); }}) .when('/', {templateUrl: 'main.html', controller: 'MyTestCtrl'}) .otherwise('/'); }) .controller('MyTestCtrl', function ($scope) { self = $scope; self.val = 'TeSt'; self.counter = 0; var self = self; self.clicked = function() { self.counter++; }; });
instead of:
router.get( '/*', function( req, res ) { express.static( indexPath )})
do
router.get( '/:anyreq', function( req, res ) { express.static( indexPath )})
just keep it at end of routes file.
It seems like there might be a problem with your AJAX requests.
I usually set up my routes like this:
app.use(express.static(path.join(__dirname, "./public")));app.use("/", require(path.join(__dirname, "./routes")));
and make calls on the front end with templateUrl: "/templates/home.html"
in a directive
or $http.get("/images").success(...).error(...)
using $http.
In the templateUrl case the app will go into the public directory, then the path templates and serve the html file.In the $http case I'm specifying a route so the app checks the public directory, doesn't see an images path and so moves on to the router. In the router I have a router.get("/images", function (req, res, next) { res.sendFile(...);
or res.send({(data)}) })
which sends the file I need back to the front end where it is caught in the success handler.