简体   繁体   中英

Node.js + Express based app not running with iisnode

I am doing some experiments with node.js + express and iisnode. I have the following very simple app, located in C:\\tsapp-deploy\\tsappsvr\\TestExpress\\0.0.0 :

app.js:

var express = require('express');
var app = express();
app.use(express.static(__dirname + "/public"));

var port = process.env.PORT || 2709;
app.listen(port, function() {
  console.log('Listening on port ' + port);
});

package.json:

{
  "name": "TestExpress",
  "version": "0.0.0",
  "private": true,
  "dependencies": {
    "express": "3.x"
  }
}

web.config:

<configuration>
  <system.webServer>
    <handlers>
      <add name="iisnode" path="app.js" verb="*" modules="iisnode" />
    </handlers>
  </system.webServer>
</configuration>

public/index.html:

<!doctype html>
<html>
<head>
  <script language="javascript" type="text/javascript" src="js/jquery.js"></script>
  <script language="javascript" type="text/javascript">
    $(document).ready(function() {
      console.log("READY!");
      $("#hello").html("Hello, World!");
    });
  </script>
</head>
<body>
  <h1 id="hello" style="text-align:center;"></h1>
</body>
</html>

My configuration is: Windows 8.1, IIS 8; iisnode version 0.2.11, node version v0.10.28.

When launched from command line ( C:\\tsapp-deploy\\tsappsvr\\TestExpress\\0.0.0>node app.js ), the app runs as expected: in the browser, I go to http://localhost:2709/ and see "Hello, World!".

My IIS is currently running other node.js-based applications not using express from similar locations (ie from C:\\tsapp-deploy\\tsappsvr\\appname\\xyz\\index.js ), so I assume it should be correctly configured, but when I try to run this app from the browser, typing http://localhost/tsappsvr/TestExpress/0.0.0/app.js I get a 404 Not Found (in IE) or a "Cannot GET /tsappsvr/TestExpress/0.0.0/app.js" in Chrome and Firefox.

I guess that the problem might be in my web.config, but I cannot figure out how to change it to get my app working. I have tried several changes to web.config as suggested in other answers to similar questions, but no success yet. Any suggestions?

Thanks in advance.

I think I have found a solution to my problem:

  • First I installed the url-rewrite extension, thanks again, David.
  • Secondly I changed my web.config as follows:

web.config:

<configuration>
  <system.webServer>
    <handlers>
      <add name="iisnode" path="app.js" verb="*" modules="iisnode" />
    </handlers>
    <rewrite>
      <rules>
        <rule name="myapp">
          <match url="/*" />
          <action type="Rewrite" url="app.js" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
  <appSettings>
    <add key="deployPath" value="/tsappsvr/TestExpress/0.0.0" />
  </appSettings>
</configuration>

Please note the deployPath key in appSettings section, whose value is set to the app's virtual path (set in IIS). In my case it is /tsappsvr/TestExpress/0.0.0 .

  • Finally, my app.js is now as follows:

app.js:

// Preamble, so to say
var express = require('express');
var http = require('http');
var app = express();

// Variable deployPath is set in web.config and must match
// the path of app.js in virtual directory.
// If app.js is run from command line:
//   "C:/tssapp-deploy/tsappsvr/TestExpress/0.0.0> node app.js"
// deployPath is set to empty string.
var deployPath = process.env.deployPath || "";

// Static content server
app.use(deployPath + "/pages", express.static(__dirname + '/public'));

// REST API handler (placeholder)
app.all(deployPath + "/api", function(req, res) {
  res.writeHead(200, {'Content-Type': 'text/html'});
  res.end("<h2>REST API Handler found.</h2>");
});

// Default handler
app.get(deployPath + "/", function(req, res) {
  res.writeHead(200, {'Content-Type': 'text/html'});
  res.end("<h2>Default Handler found.</h2>");
});

// Not Found handler
app.use(function(req, res, next){
  res.writeHead(404, {'Content-Type': 'text/html'});
  res.write("<h2>The requested resource is not available.</h2>");
  res.write("Request received on port " + process.env.PORT + "<br>");
  res.write("Request URL: " + req.url + "<br>");
  res.write("Deploy Path: " + deployPath + "<br>");
  res.end('[iisnode version is ' + process.env.IISNODE_VERSION + ', node version is ' + process.version + ']');
});

// Server creation
var server = http.createServer(app);
var port = process.env.PORT || 2709;
server.listen(port);

Variable deployPath is used as a prefix for all handlers (except the "Not Found" handler). When app.js is launched from iisnode, deployPath it is part of process.env , while it is undefined if app.js is launched from command line (eg C:/tsapp-deploy/tsappsvr/TestExpress/0.0.0>node app.js ). This ensures that app.js works in both cases.

Now, typing http://localhost/tsappsvr/TestExpress/0.0.0/ in the browser I fire the default handler; appending /pages to the former URL I have access to static content, while appending /api I fire the REST API handler. The same happens for http://localhost:2709/ as base URL.

Eric, have you install the url-rewrite extension ?

Here is the configuration I have in my web.config:

<configuration>
 <system.webServer>

  <handlers>
   <add name="iisnode" path="app.js" verb="*" modules="iisnode" />
  </handlers>

  <rewrite>
    <rules>
      <rule name="myapp">
        <match url="/*" />
        <action type="Rewrite" url="app.js" />
      </rule>
    </rules>
  </rewrite>
 <system.webServer>    
<configuration>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM