Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 (i.e. from C:\tsapp-deploy\tsappsvr\appname\x.y.z\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.

like image 871
eca Avatar asked Jun 09 '14 15:06

eca


2 Answers

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 (e.g. 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.

like image 128
eca Avatar answered Sep 28 '22 07:09

eca


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>
like image 27
David Dias Avatar answered Sep 28 '22 07:09

David Dias