nodejs hapi单个页面

我有一个单一的应用程序站点(NodeJS),我想从Express迁移到Hapi,我通常做的是提供静态文件,并将其他所有内容路由到包含angularjs应用程序和angular度路由configuration的单个页面。

// Express routing, first the static files app.use( express.static(__dirname + '/public') ); // Second the api routes app.get('/api', function(req, res){ res.send( {api: 'response' } ) }); // Finally everything else maps to the single page app: app.get('*', function(req, res){ res.sendfile('./public/html/controllers.index.html') }); 

在HapiJS我不知道如何复制相同的代码(不使用express.static中间件),因为:

 Hapi = require('hapi'); var server = new Hapi.Server('localhost', 84); server.route({ method: 'GET', path: '/{p*}', handler: function (request, reply) { reply.file('public/html/index.html'); } }); 

在上面的代码中,无论将哪个请求映射到我的单个页面('public / html / index.html'),但是如果我这样做,那么js,css,jpg&files将被映射到相同的文件,而不是脚本,样式和图像(一个'/images/bg.png'的请求将下载单个页面,而不是图像文件)。

我知道,如果我将path“/”设置为单个页面,然后将“{p *}”设置为“{directory:{path:'/ public'}}”,那么我将拥有需要的行为如果某个用户复制并粘贴特定的URL(可以说是“/ account / login”)然后回车,该路由将被映射到HapiJS中,并且响应将是“未find(404)”,angular路由将永远无法回应。

有人知道如何解决这个问题吗?

问题的关键部分是:

  • 只使用HapiJS(不包括快递或其他中间件)
  • 不要路由每一个angular度的路线(只是路由的其他一切尚未路由到单个页面的angular度可以处理路由)

不知道这是否会帮助你,但是你的起始代码对于Hapi.js有点“奇怪”。 这是我用来build立一个简单的hapi.js SPA。

如果您希望使用特定的URL(例如帐户/login),则必须将您的path指向特定的部分(path:'/ account / login')

不同之处在于,我指的是整个目录, 不同的文件,你只需回复index.html文件。 列表参数让你决定是否要显示目录结构或不在你的url。 默认是false。

更多信息在这里: http : //hapijs.com/tutorials/serving-files#directory-handler

 var Hapi = require('hapi'); var Path = require('path'); var server = new Hapi.Server(8080, 'localhost'); server.route({ method: 'GET', path: '/{path*}', handler: { directory: { path: './public', listing: false, index: true } } }); server.start(function(){ console.log('server started'); }); 

受惰性文档的启发,我通过静态目录中的所有东西来解决这个问题。 然后,我添加了一个onPostHandler来返回索引文件,每当一个404即将被返回。 客户端路由器然后可以发送redirect到静态文件目录中的现有404.html文件。

 // Static Assets server.route({ method: 'GET', path: '/{param*}', handler: { directory: { path: ['app/static'], listing: false, index: ['index.html'] } } }); // return index.html for everything else server.ext('onPostHandler', (request, reply) => { console.log('WORD'); const response = request.response; if (response.isBoom && response.output.statusCode === 404) { return reply.file('app/static/index.html'); } return reply.continue(); }); 

这个答案是无效的。 正如@Al jey在评论中所说。 哈比有自己的algorithm来sorting路线,请不要跟随这个答案。


与expressJS类似,Hapi按顺序处理路由。 只要优先定义路线顺序:

 server.route( { // Angular/API Route method: 'GET', path: '/api', handler: function (request, reply) { reply( {api: 'response' } ) } }); server.route({ // Other assets If you have method: 'GET', path: '/assets/{param*}', handler: { directory: { path: './assets', listing: false, index: true } }); server.route({ // Everything else method: 'GET', path: '/{p*}', handler: function (request, reply) { reply.file('public/html/index.html'); } }); 

我像这里所描述的那样有惰性的成功。 如果向下滚动,则可以find“目录处理程序”部分。

我的解决scheme如下所示:

 var Hapi = require('hapi'); var Path = require('path'); var server = new Hapi.Server(); server.connection({ host: 'localhost', port: 8001 }); server.register(require('inert'), (err) => { if (err) { throw err; } server.route({ method: 'GET', path: '/{param*}', handler: { directory: { path: 'public' } } }); server.start((err) => { if (err) { throw err; } console.log('Server running at:', server.info.uri); }); }); 

确保你有一个惰性的插件。

在你的server.js(或者你命名的任何东西)中,configuration相对path来提供静态文件,见下文

 const server = new Hapi.Server({ connections: { routes: { cors: true, files: { relativeTo: Path.join(__dirname, 'public') } }, router: { stripTrailingSlash: true } } })