IIS,Node.js和Web应用程序与IISNode没有configuration正确的虚拟目录

我在IIS中有以下设置:

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

我不能为了我的生活得到这个东西configuration正确,所以当我打networking应用程序是正确地提供节点应用程序。 我认为我的问题在于web.config。 任何人都可以帮我写一个正确的web.config来正确地工作? 我的configuration的当前版本将服务于我的节点响应,说它无法获取我input的任何url的资源。

这是我的configuration的当前版本:

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

       

网上收集的解决方案 "IIS,Node.js和Web应用程序与IISNode没有configuration正确的虚拟目录"

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

经过大量时间浪费和挣扎,我可以把所有的东西放在一起,让我的应用程序在虚拟目录中工作,这包括使用Socket.io

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

我强烈build议使用下面的Web.config模板来使这个工作。

IISNode Web.config模板

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

在上面的链接configuration有一些评论,我放在那里,以帮助易用性。 它被configuration为使用app.js作为主文件,但是如果你的文件被命名为不同的东西,只需将该值改为使用该文件。

为了使这个configuration工作,如果你还没有安装它,你将需要IIS的URL重写模块 。

默认设置

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

快速使用您的虚拟目录

IISNode将在<appSettings>环境variables中声明所有的键。 我们可以利用这个优势来设置我们的虚拟目录path,并将其暴露给我们的主文件。 在上面的模板中,我们的主文件是app.js

获取我们的虚拟目录path

我们需要从我们的Web.config文件中获取应用程序的path。 我们通过访问我们的过程对象上的环境variables来做到这一点。 app.js下行添加到我们的app.js文件中。

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

这从我们的Web.config中检索我们的virtualDirPath,并给它一个空string的默认值。

路由页面

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

 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和Socket.io

当使用虚拟目录与Socket.io时,我们需要更改服务器和客户端的configuration。

服务器端

我们需要configuration我们的Socket.io服务器,与通常的情况稍有不同。

 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服务器来操作我们的虚拟path而不是默认path( '/socket.io'是默认path)。

Web.config更改

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

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

然后我们需要添加我们的url重写为Socket.iopath

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

客户端

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

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

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

环境信息

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

我遇到了同样的问题 。

最终,什么工作是在我的应用程序中修复请求的url。 我们已经从使用express转换为hapi,所以我把这个代码从hapi转换回来,而不用先testing它,但它应该让你进入大局。

 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...