Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript ExpressJS服务器-如何处理多个域_Javascript_Node.js_Express - Fatal编程技术网

Javascript ExpressJS服务器-如何处理多个域

Javascript ExpressJS服务器-如何处理多个域,javascript,node.js,express,Javascript,Node.js,Express,我在玩Express,我想知道“最正确”的方法是处理链接到同一服务器的多个域 假设我们有 foo.com bar.net baz.com 都指向111.222.333.444。那台机器正在用快车运行NodeJS。我当前的解决方案如下所示: var express = require( 'express' ), app = module.exports = express.createServer(), // ... more lines ... app.get( '/', r

我在玩Express,我想知道“最正确”的方法是处理链接到同一服务器的多个域

假设我们有

  • foo.com
  • bar.net
  • baz.com
都指向
111.222.333.444
。那台机器正在用快车运行NodeJS。我当前的解决方案如下所示:

var express = require( 'express' ),
    app     = module.exports = express.createServer(),
// ... more lines ...
app.get( '/', routes.index.bind( app ) );
express.createServer()
.use(express.vhost('hostname1.com', require('/path/to/hostname1').app)
.use(express.vhost('hostname2.com', require('/path/to/hostname2').app)
.listen(80)
到目前为止,这是相当简单的。目前唯一的例外是在我的
应用程序中。配置
调用,我没有调用
。使用(express.static())
。这是因为
.routes.index()
方法现在看起来是这样的:

var fs    = require( 'fs' ),
// ... more lines ...

exports.index = function( req, res ) {
    var host = /(\w+\.)?(.*)\.\w+/.exec( req.header( 'host' ) ),
        app  = this;

    switch( host[ 2 ] ) {
        case 'foo':
            app.use( express.static( '/var/www/foo' ) );
            fs.readFile( '/var/www/foo/index.html', 'utf8', fileReadFoo );
            break;
        case 'bar':
            app.use( express.static( '/var/www/bar' ) );
            fs.readFile( '/var/www/bar/index.html', 'utf8', fileReadBar );
            break;
        case 'baz':
            // ... lines ...
            res.render( 'index', { title: 'Baz Title example' } );
            break;
        default:
            res.send('Sorry, I do not know how to handle that domain.');
    }

    function fileReadFoo( err, text ) {
        res.send( text );
    }

    function fileReadBar( err, text ) {
        res.send( text );
    }
};
这里发生的是,我分析
host
条目的
req.header
,并解析域名。基于此,我调用
.static()
方法,以便Express能够提供正确的静态资源等,而且,我只需读取并发送index.html文件的内容。我也尝试使用Jade来提供普通HTML文件,但是Jade中的
include
指令只接受相对路径

然而,这确实有效,但我很不确定这是否是一个好的做法

欢迎提供任何建议/帮助


更新

我想我需要更清楚地说明这一点。我决不是初学者。我非常了解ES和其他服务器(如NGINX)的工作原理。我正在寻找关于NodeJS/Express的正确答案。如果使用Node/Express对此没有任何意义,请详细说明。如果使用Node/Express有更好的方法,请解释

谢谢:-)

我使用node.js作为前端服务器。它是组织域、静态内容交付、负载控制和许多其他强大功能的最佳解决方案。绝对不需要在节点事件循环中执行此操作。这将决定应用程序的速度。

Vadim是。您可以使用以下配置如何响应每个域:

routes.index
可以简化为只处理
baz.com
请求:

exports.index = function( req, res ) {
    // ... lines ...
    res.render( 'index', { title: 'Baz Title example' } );
};
编辑

至于比较:

首先有效地执行
开关
,并确定如何基于
主机处理所有请求
——类似于:

express.createServer().use(function( req, res, next ) {
    switch( req.host ) {
        case 'foo.com': express.static( '/var/www/foo' )( req, res, next ); break;
        case 'bar.net': express.static( '/var/www/bar' )( req, res, next ); break;
        case 'baz.com': app.handle( req, res, next ); break;
        default: res.send( ... );
    }
}).listen( ... );
它允许您在启动时设置堆栈,以便任何中间件立即可用:

server.stack = [
    express.vhost( 'foo.com', ... ),
    express.vhost( 'bar.net', ... ),
    express.vhost( 'baz.com', ... ),
    [Function]
];
// GET http://foo.com/file 404
app.stack = [ app.router ]

// GET http://foo.com/ 200
app.stack = [ app.router, express.static( '/var/www/foo' ) ]

// GET http://foo.com/file 200
app.stack = [ app.router, express.static( '/var/www/foo' ) ]
这些也反映了您可能遇到的问题的两个可能来源:

没有过滤器的相同堆栈

每个
应用程序
只有一个中间件堆栈,您使用的所有中间件都将通过
应用程序直接添加到该堆栈中。使用(…)
。尽管在条件下添加了一些,但您仍然可以:

app.stack = [
    // ...,
    app.router,
    express.static( '/var/www/foo' ),
    express.static( '/var/www/bar' )
];
而且该条件不会改变
静态
中间件的响应方式——即通过
req.path
,而不是
req.host
——仅当它们在堆栈中开始响应时

堆栈状态

而且,如果在发出另一个请求后才添加
静态
中间件,那么我认为它们不会立即可用:

server.stack = [
    express.vhost( 'foo.com', ... ),
    express.vhost( 'bar.net', ... ),
    express.vhost( 'baz.com', ... ),
    [Function]
];
// GET http://foo.com/file 404
app.stack = [ app.router ]

// GET http://foo.com/ 200
app.stack = [ app.router, express.static( '/var/www/foo' ) ]

// GET http://foo.com/file 200
app.stack = [ app.router, express.static( '/var/www/foo' ) ]
这也可能意味着相同的
静态
中间件可以多次添加到堆栈中:

// 3x GET http://foo.com/
app.stack = [
    app.router,
    express.static( '/var/www/foo' ),
    express.static( '/var/www/foo' ),
    express.static( '/var/www/foo' )
]
让它们的添加取决于其他请求也意味着可能的竞争条件:

// was `foo.com` or `bar.net` first?
app.stack = [
    app.router,
    express.static( ? ),
    express.static( ? )
]
我喜欢用作前端反向代理-这允许您将完全不同的express堆栈作为不同的服务器进程运行(每个进程具有不同的功能,并且为了健壮性而分开)

然后,您可以决定如何路由到不同的端口,这对WebSocket很好

var bouncy = require('bouncy');

bouncy(function (req, bounce) {
    if (req.headers.host === 'bouncy.example.com') {
        bounce(8000);
    }
    else if (req.headers.host === 'trampoline.example.com') {
        bounce(8001)
    }
}).listen(80);

我不得不说,我不认为这样做有什么意义。Node.js具有一个流程设计约束。限制IO对于一个web应用程序来说是一项艰巨的工作,更不用说少数web应用程序了。试图通过使用多个应用程序来抽象这一点会使代码过于复杂,使其无法读取。单个应用程序中的错误可能会影响所有应用程序。这是一个非常不稳定的配置

如果你想看看你是否能做到,我想答案是肯定的。在另一个答案中,类似于vhost的建议。另一方面,我可能会采取某种分离关注点的方式,限制我的应用程序。如果要将其放置在同一服务器盒中,我将执行以下操作:

  • 可用核心数-1是我绑定到单个服务器的域数
  • 每个核心将包含一个绑定到它的node.js进程。它将实现覆盖单个网站的单个web应用程序
  • 备用核心将容纳某种类型的“路由器”,可以是nginx解决方案,也可以是路由数据的node.js/express应用程序 简言之,不要想着做大,想想做大

    缺点: 这是一种不同的缩放方式。你从一个盒子里只能得到这么多的果汁。当我们谈论“多盒子”环境时,我不知道如何扩展这个想法

    由于Express使用,我很确定您可以使用Connect的虚拟主机中间件。它的操作与其他产品上的其他vhost模块类似。我没有多个域来测试并向您展示正确的代码,但我认为是这样的:

    var express = require( 'express' ),
        app     = module.exports = express.createServer(),
    // ... more lines ...
    app.get( '/', routes.index.bind( app ) );
    
    express.createServer()
    .use(express.vhost('hostname1.com', require('/path/to/hostname1').app)
    .use(express.vhost('hostname2.com', require('/path/to/hostname2').app)
    .listen(80)
    

    如果一台Express服务器还不够,那么可以从API中查看Node.Cluster的使用情况。如果这还不够,那么当前的做法是在Express服务器前面放置一个asnyc反向代理,如Nginx,并将代理指向Express服务器。

    如果不知道约束条件,就很难回答这个问题,这意味着必须在同一进程中运行主机,因此,我将附和其他人所说的,但希望给出更多的上下文

    使用node的“最正确”方法是在多个进程中运行主机,并在多个进程中反向代理请求