【问题标题】:How do I support multiple websites on the same server with hapi.js?如何使用 hapi.js 支持同一服务器上的多个网站?
【发布时间】:2016-06-12 10:51:00
【问题描述】:

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

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

我怎样才能用 hapi 来实现呢?

【问题讨论】:

    标签: javascript node.js virtualhost hapijs


    【解决方案1】:

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

    这是一个例子:

    sites/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

    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 配置正确)。

    【讨论】:

    • 如何提供模板?
    【解决方案2】:

    如果您使用的是 Hapi 版本 >= 17,则细节略有变化,但思路相同。

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

    在下面的示例中,插件不会知道或关心它们在哪个域上提供服务。

    代码

    猫插件

    这是用于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.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!'
          }
        })
      }
    }
    

    主服务器

    这是指定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()
    

    结果

    访问不同的版本

    启动服务器

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

    采样服务器输出

    $ 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

    【讨论】:

    • 感谢更新
    猜你喜欢
    • 2019-08-05
    • 1970-01-01
    • 2012-07-30
    • 2018-11-02
    • 1970-01-01
    • 1970-01-01
    • 2012-03-22
    • 2012-12-05
    • 1970-01-01
    相关资源
    最近更新 更多