如何使用hapi.js在同一台服务器上支持多个网站?

问题描述 投票:7回答:2

假设我想在同一台服务器上使用单个IP地址(即使用虚拟主机)托管我的2个网站(cats.com和dogs.com)。我想用hapi.js编写它们并将它们作为单个进程运行。

这些站点可能有重叠的路径,例如它们可能都有/about页面。

我怎么能用hapi实现这个呢?

javascript node.js virtualhost hapijs
2个回答
4
投票

使用hapi实现这一目标的一个好方法是将不同的网站放在单独的plugins中,并在加载插件时使用vhost修饰符,理想情况下使用Glue

这是一个例子:

网站/ dogs.js

exports.register = function (server, options, next) {

    // Put all your routes for the site in here

    server.route({
        method: 'GET',
        path: '/',
        handler: function (request, reply) {

            reply('Dogs homepage');
        }
    });

    next();
};

exports.register.attributes = { name: 'dogs' };

网站/ cats.js

exports.register = function (server, options, next) {

    // Put all your routes for the site in here

    server.route({
        method: 'GET',
        path: '/',
        handler: function (request, reply) {

            reply('Cats homepage');
        }
    });

    next();
};

exports.register.attributes = { name: 'cats' };

index.js

const Glue = require('glue');
const Hoek = require('hoek');

const manifest = {
    connections: [{
        port: 4000,
    }],
    registrations: [
        {
            plugin: {
                register: './sites/cats'
            },
            options: {
                routes: {
                    vhost: 'cats.com'
                }
            }
        },
        {
            plugin: {
                register: './sites/dogs'
            },
            options: {
                routes: {
                    vhost: 'dogs.com'
                }
            }
        }
    ]
};

const options = {
    relativeTo: __dirname
};

Glue.compose(manifest, options, (err, server) => {

    Hoek.assert(!err, err);
    server.start((err) => {

        Hoek.assert(!err, err);
        console.log('server started');
    });
});

然后,您可以使用几个cURL命令确认路由是否正常工作:

$ curl -H "Host: cats.com" localhost:4000/
Cats homepage

$ curl -H "Host: dogs.com" localhost:4000/
Dogs homepage

浏览器会为您设置Host标头,因此当您浏览到http://cats.comhttp://dogs.com时,hapi将为您提供正确的内容(前提是您的DNS配置正确)。


0
投票

如果你使用的是Hapi版本> = 17,虽然想法是一样的,但细节略有改变。

我们希望每个站点都有一个插件。然后,一旦我们将每个站点提取到一个插件(下面的catsdogs)中,我们就可以使用glue组成单独的配置并使用hapi为站点提供服务。

在下面的示例中,插件不会知道或关心它们所服务的域。

The Code

Cats Plugin

这是与cats.com一起使用的“服务器”。它在根路径Hello Cats!返回文本/。在现实生活中它会做一些更有用的事情,你可能会在一个真实的项目中有更多的路线和处理程序,但这个想法仍然是一样的。

// ./sites/cats.js
exports.plugin = {
  name: 'cats',
  version: '1.0.0',
  register: async function(server, options) {
    server.route({
      method: 'GET',
      path: '/',
      handler: (request, h) => {
        return 'Hello Cats!'
      }
    })
  }
}

Dogs Plugin

这是dogs.com上出现的内容的服务器。它与cats插件完全相同,只是它返回文本Hello Dogs!。同样,这不是一个有用的插件,它仅用于说明。

// ./sites/dogs.js
exports.plugin = {
  name: 'dogs',
  version: '1.0.0',
  register: async function(server, options) {
    server.route({
      method: 'GET',
      path: '/',
      handler: (request, h) => {
        return 'Hello Dogs!'
      }
    })
  }
}

Main Server

这是指定vhost的地方,为主机cats.comdogs.com分配插件。

// ./server.js
const Hapi = require('hapi')
const Glue = require('glue')

const manifest = {
  server: {
    host: process.env.HOST || '0.0.0.0',
    port: process.env.PORT || 8080
  },
  register: {
    plugins: [
      {
        plugin: './sites/cats',
        routes: {
          vhost: 'cats.com'
        }
      },
      {
        plugin: './sites/dogs',
        routes: {
          vhost: 'dogs.com'
        }
      }
    ]
  }
}

const options = {
  relativeTo: __dirname
}

const startServer = async function () {
  try {
    const server = await Glue.compose(manifest, options)
    await server.start()
    console.log('Hapi days for Cats and for Dogs!')
  }
  catch (err) {
    console.error(err)
    process.exit(1)
  }
}

startServer()

The Result

访问不同的版本

Starting the Server

$ node server.js
Hapi days for Cats and for Dogs!

Sampling Server Output

$ curl -H "Host: cats.com" localhost:8080/
Hello Cats!

$ curl -H "Host: dogs.com" localhost:8080/
Hello Dogs!

$ curl localhost:8080/
{"statusCode":404,"error":"Not Found","message":"Not Found"}

$ curl -H "Host: platypus.com" localhost:8080/
{"statusCode":404,"error":"Not Found","message":"Not Found"}

请注意,默认主机没有路由,因此不指定主机将导致返回404

© www.soinside.com 2019 - 2024. All rights reserved.