nodejs hapi single page

戏子无情 提交于 2019-11-30 08:58:49

Not sure if this will help you out but your starting code is a bit "odd" for Hapi.js. This is what i use to set up a simple hapi.js SPA.

If you wish to use specific URLS like the Account/Login, you have to direct your path to that specific section.(path: '/account/login')

The difference lies in the fact that i'm pointing to the directory as a whole, incl. the different files, and you simply reply the index.html file. The listing parameter lets you decide if you want to show directory structure or not in your urls. Default is false.

More info here: 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');
});

Inspired by the inert documentation, I solved this by serving everything out of a static directory. Then I added an onPostHandler to return the index file whenever a 404 was about to be returned. You client side router could then send a redirect to an existing 404.html file in the static files directory.

// 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();
});

This answer is invalid. As @Al jey said in the comment. Hapi have their own algorithm to sort the routes, please don't follow this answer.


Similar to expressJS, Hapi handle route by order. Just define routes order by priority:

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

i had success with inert like described here. If you scroll down, you can find the section "Directory handler".

My solution looks like that:

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

Make sure you have inert as a plugin.

In your server.js (or whatever you named it), configure the relative path to serve static files see below

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

then for your route, register a new route plugin like below. This is assuming you entry index.html (for React or Angular) is inside the public directory as configured above

exports.register = (server, options, next) => {
  server.route([{
    method: 'GET',
    path: '/{param*}',
    handler: {
      directory: {
        path: '.',
        redirectToSlash: true,
        listing: false,
        index: true
      }
    }
  }])
  server.ext('onPostHandler', (req, res) => {
    const response = req.response
    if (response.isBoom && response.output.statusCode >= 404) {
      return res.file('index.html')
    }
    return res.continue()
  })
  next()
}

exports.register.attributes = {
  name: 'static-route',
  version: '1.0.0'
}

Now everytime HapiJS throws a 404 error, the route it is forwarded to your React / Angular App, which can then handle the route if it exists.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!