IIS,Node.js和未使用虚拟目录正确配置IISNode的Web应用程序

时间:2013-04-12 20:00:28

标签: node.js iis express iisnode

我在IIS中进行了以下设置:

  • 托管标准html网站的默认网站(www.foo.com)
  • 运行IIS节点的默认网站(www.foo.com/bar)下的Web应用程序
  • 节点项目正在使用快递

我不能为我的生活让这个东西正确配置所以当我点击Web应用程序正确地提供节点应用程序。我认为我的问题在于web.config。任何人都可以帮我写一个正确的web.config来使这个工作正常吗?我的配置的当前版本将为我提供一个节点响应,该响应表明它无法在我键入的任何URL中获取资源。

以下是我的配置的当前版本:

<configuration>
  <system.webServer>    
    <handlers>
      <add name="iisnode" path="app.js" verb="*" modules="iisnode" />
    </handlers>    
    <rewrite>
      <rules>
        <rule name="bar">
          <match url="bar/*" />
          <action type="Rewrite" url="app.js" />
        </rule>
      </rules>
    </rewrite>    
  </system.webServer>
</configuration>

3 个答案:

答案 0 :(得分:23)

前一段时间我遇到了同样的问题,在虚拟目录中运行我的应用程序。

经过大量浪费和挣扎之后,我能够将所有部分放在一起,让我的应用程序在虚拟目录中运行,这包括使用Socket.io的应用程序

由于没有太多关于此特定方案和可用资源的文档,我发现,仅部分描述了如何解决此问题。这是一个如何使所有这些工作的教程。我个人有多个Node.js Web服务使用此设置实现REST API或Socket.io。

我强烈建议您使用下面的Web.config模板来实现此功能。

IISNode Web.config模板

https://gist.github.com/pbaio/f63918181d8d7f8ee1d2

上面链接中的配置有一些注释我放在那里以帮助易用。它配置为使用app.js作为主文件,但如果您的文件被命名为不同的东西,只需切换值以使用该文件。

要使此配置正常运行,如果您尚未安装此配置,则需要URL Re-write Module for IIS

默认设置

默认情况下,此模板设置为在IIS中运行的标准Web App中运行,而不是在虚拟目录环境中运行。但是,通过一些小的调整,您可以使用相同的Web.config在虚拟目录中运行Node.js应用程序。

让Express使用您的虚拟目录

IISNode会在您的<appSettings>环境变量中声明所有键。我们可以利用它来设置我们的虚拟目录路径并将其公开给我们的主文件。在上面的模板中,我们的主文件是app.js

获取我们的虚拟目录路径

我们需要在Web.config文件中获取应用程序路由的路径。我们通过访问流程对象上的环境变量来实现此目的。将以下行添加到我们的app.js文件中。

var virtualDirPath = process.env.virtualDirPath || '';

这将从我们的Web.config中检索我们的virtualDirPath,并为其提供一个默认值为empty string。

路由页面

然后我们可以将virtualDirPath添加到我们的路由中,如果您使用的是Jade或EJS等视图引擎,我们可以将超链接的虚拟目录路径传递给视图:

var app = require('express')();
app.get(virtualDirPath + '/', function(req, res) {
  res.render('index', { virtualDirPath: virtualDirPath });
});

静态内容

我们可以轻松地提供以下服务:

app.use(express.static(path.join(virtualDirPath, 'public')));

如果你使用的是Bower.io:

app.use('/bower_components', express.static(path.join(virtualDirPath,'bower_components')));

使用Express&amp ;;的虚拟目录Socket.io

使用带有Socket.io的虚拟目录时,我们需要更改服务器和客户端的配置。

服务器端

我们需要配置我们的Socket.io Server,与通常情况略有不同。

var app = require('express')();

var virtualDirPath = process.env.virtualDirPath || '';

var server = require('http').Server(app);
var io = require('socket.io')(server, { path: virtualDirPath + '/socket.io' });
// Get the port that we should be listening on
server.listen(process.env.PORT || 8080);

在上面的代码中,我们修改了我们的Socket.io服务器以在virtualDirpath上操作,而不是默认路径('/socket.io'是默认路径)。

Web.config更改

为了让IISNode能够正确使用socket.io,我们还需要添加一些额外的url重写并交换掉我们的处理程序。在上面的模板配置文件中,我们可以在第57行看到Socket.io处理程序,它在模板中被注释掉。

<add name="iisnode-socket.io" path="app.js" verb="*" modules="iisnode" />

然后我们需要为Socket.io路径添加我们的url重写

<rule name="SocketIO" patternSyntax="ECMAScript">
    <match url="socket.io.+" />
    <action type="Rewrite" url="app.js"/>
</rule>

客户端

在客户端,我们只需要指定Socket.io服务器正在侦听的路径而不是其默认路径。

var socket = io.connect('http://example.com:port', { path: '/virtualDirPath/socket.io' });

此时,使用IISNode在虚拟目录中运行的Socket.io应用程序,一切都应该很好。

环境信息

使用此配置的应用程序是使用Node.js,Express 4.12.3构建的,并在安装了IISNode的IIS 7.5中运行。此外,通过更改conifg文件中的处理程序,Socket.io也可以在虚拟目录中使用。上例中使用的Socket.io版本是1.3.5

答案 1 :(得分:0)

我遇到了this same problem

最终,有效的方法是在我的应用程序中修复请求URL。我们已经从使用express转换为hapi,所以我已经将这些代码从hapi转换回express而不先测试它,但它应该让你进入大球场。

app.use(function (req, res, next) {
    if(!settings.serverPath) return next();

    console.log(req.url);
    var regex = new RegExp('(' + settings.serverPath + ')(/.+)', "i");
    req.url = req.url.replace(regex, "$2");
    console.log(req.url);
    return reply.continue();
});

//set up your routes here...

答案 2 :(得分:0)

对于那些无法提供静态文件的人,请确保在进行构建之前将基本href url更改为虚拟目录路径,然后从服务器提供静态文件。希望这有助于某人。