简体   繁体   English

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

[英]How do I support multiple websites on the same server with hapi.js?

Let's say I want to host my 2 websites (cats.com and dogs.com) on the same server with a single IP address (ie with virtual hosts). 假设我想在同一台服务器上使用单个IP地址(即使用虚拟主机)托管我的2个网站(cats.com和dogs.com)。 I want to write them both with hapi.js and have them running as a single process. 我想用hapi.js编写它们并将它们作为单个进程运行。

The sites may have overlapping paths, for instance they might both have a /about page. 站点可能具有重叠路径,例如它们可能都具有/about页面。

How could I implement this with hapi? 我怎么能用hapi实现这个呢?

A nice way of achieving that with hapi is by putting your different sites in to separate plugins and using the vhost modifier when loading the plugin, ideally using Glue . 使用hapi实现这一目标的一个好方法是将不同的站点放入单独的插件中,并在加载插件时使用vhost修饰符,理想情况下使用Glue

Here's an example: 这是一个例子:

sites/dogs.js 网站/ 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' };

sites/cats.js 网站/ 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 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');
    });
});

You can then confirm that the routing works correctly with a couple of cURL commands: 然后,您可以使用几个cURL命令确认路由是否正常工作:

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

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

A browser will set that Host header for you though so when you browse to http://cats.com or http://dogs.com hapi will serve you the correct content (provided your DNS is configured correctly). 浏览器会为您设置主机标题,因此当您浏览到http://cats.comhttp://dogs.com时, hapi将为您提供正确的内容(前提是您的DNS配置正确)。

If you are using a Hapi version >= 17, the details have changed slightly, though the idea is the same. 如果你使用的是Hapi版本> = 17,虽然想法是一样的,但细节略有改变。

We will want to have a plugin for each site. 我们希望每个站点都有一个插件。 Then, once we have each site extracted into a plugin ( cats and dogs below), we can compose the separate configurations using glue and serve the site with hapi . 然后,一旦我们每个网站提取到一个插件( catsdogs以下),我们可以使用组成不同的配置glue与服务网站hapi

In the example below, the plugins will not know or care which domain they are being served on. 在下面的示例中,插件不会知道或关心它们所服务的域。

The Code 编码

Cats Plugin 猫插件

This is the "server" that's meant to be used with cats.com . 这是与cats.com一起使用的“服务器”。 It returns the text Hello Cats! 它返回文本Hello Cats! at the root path, / . 在根路径, / In real life it would do something more useful, and you would likely have many more routes and handlers in a real project, but the idea remains the same. 在现实生活中它会做一些更有用的事情,你可能会在一个真实的项目中有更多的路线和处理程序,但这个想法仍然是一样的。

// ./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 狗插件

This is the server for the content appearing at dogs.com . 这是dogs.com显示内容的服务器。 It is exactly the same as the cats plugin, except it returns the text Hello Dogs! 它与cats插件完全相同,除了它返回文本Hello Dogs! . Again, this is not a useful plugin, it is for illustration only. 同样,这不是一个有用的插件,它仅用于说明。

// ./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 主服务器

This is where the vhost is specified, assigning plugins to hosts cats.com and dogs.com . 这是指定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 结果

Accessing the different versions 访问不同的版本

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"}

Note that there are no routes for the default host, so not specifying a host will result in a 404 being returned. 请注意,默认主机没有路由,因此不指定主机将导致返回404

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM