为了账号安全,请及时绑定邮箱和手机立即绑定

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

/ 猿问

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

白板的微信 2019-12-04 12:53:29

我在IIS中具有以下设置:


默认网站(www.foo.com)托管标准html网站

运行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 回答

?
慕莱坞7535251

不久前,我在虚拟目录中运行我的应用程序时遇到了相同的问题。


经过大量的时间浪费和苦苦挣扎之后,我得以将所有部分组合在一起以使我的应用程序可以在虚拟目录中工作,其中包括使用Socket.io的应用程序


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


我强烈建议使用下面的Web.config模板来使此工作正常。


IISNode Web.config模板

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


上面链接中的配置有一些注释,我在其中添加了一些注释,以帮助简化使用。它被配置为使用app.js作为主文件,但是如果您的文件命名不同,则只需将值切换为使用该文件即可。


要使此配置正常工作,如果您尚未安装IIS,则需要URL重写模块。


默认设置

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


获取Express以使用您的虚拟目录

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


获取我们的虚拟目录路径

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


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

这将从我们的Web.config中检索我们的virtualDirPath,并将其默认值为空字符串。


路由页面

然后,我们可以将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&Socket.io中使用虚拟目录

将虚拟目录与Socket.io结合使用时,我们需要对服务器和客户端的配置进行更改。


服务器端

我们需要将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服务器以使其在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' });

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


环境信息

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


查看完整回答
反对 回复 2019-12-04
?
一只萌萌小番薯

对于那些无法提供静态文件的用户,请确保在执行ng build之前将您的基本href URL更改为虚拟目录路径,然后从服务器提供您的静态文件。希望对您有所帮助。


查看完整回答
反对 回复 2019-12-04
?
慕斯卡3215842

最终,有效的方法是在我的应用程序中修复了请求网址。我们已经从使用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...


查看完整回答
反对 回复 2019-12-04

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信