-->

Serving static files from iisnode with URL Rewrite

2019-02-26 00:48发布

问题:

I am using a Rewrite rule in my web.config file for a node app running under issnode to point to my server.js file. myapp/* points to server.js.

    <rule name="myapp" enabled="true">
      <match url="myapp/*" />
      <action type="Rewrite" url="server.js" />
    </rule>

This has been working great www.mywebsite.com/myapp/ would load a run my app. What I wanted was to have a redirect from the root of the website so www.mywebsite.com/ would run my app. So I changed my web.config file

    <rule name="myapp" enabled="true">
      <match url="/*" />
      <action type="Rewrite" url="server.js" />
    </rule>

So this is running the server.js and serving up a my a static html file, the only problem is referencing any external files from my html file (css, js, images etc) Just get 500s for every request. I am using this to serve static files

        var libpath = require('path');
        var _path = "."; <-- This seems to be the problem


        var uri = url.parse(req.url).pathname;
    var filename = libpath.join(_path, uri);
    fs.readFile(filename, "binary", function (err, file) {
            if (err) {
            res.writeHead(500, {
                "Content-Type": "text/plain"
            });
                 res.write(err + "\n");
                 res.end();
                return;
            }

         var type = mime.lookup(filename);
            res.writeHead(200, {
                "Content-Type": type
            });
         res.write(file, "binary");
         res.end();
        });

    break;

So my question is how to point to root of my node app / server to serve up static files.

Thanks

Jono

回答1:

The best way to serve static content in iisnode is to configure the URL rewriting module such that the IIS static file handler handles requests for static content rather than node.js. Having IIS serve static content has a large performance benefit over serving these files using any node.js mechanisms due to kernel level optimizations around caching and just not having to break into JavaScript code.

For a boilerplate web.config configuration that achieves this see https://github.com/tjanczuk/iisnode/issues/160#issuecomment-5606547



回答2:

I had some issues using the suggested rule config, so I made some changes:

<system.webServer>
  <handlers>
    <clear />
    <add name="iisnode" path="/index.js" verb="*" modules="iisnode" />
    <add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" />
  </handlers>
  <rewrite>
    <rules>
      <rule name="static">
        <action type="Rewrite" url="www{REQUEST_URI}" />
      </rule>
      <rule name="serve-static" stopProcessing="true">
        <conditions logicalGrouping="MatchAny">
          <add input="{REQUEST_FILENAME}" matchType="IsFile" />
          <add input="{REQUEST_URI}" pattern="^/www/$" />
        </conditions>
      </rule>
      <rule name="node">
        <action type="Rewrite" url="index.js" />
      </rule>
    </rules>
  </rewrite>
</system.webServer>
  • First rule prefixes all requests with www, my client directory.
  • Second rule stops processing if the file exists or if the root path is requested
  • Third rule rewrites anything else to the name of my backend Node script so that it can be picked up by the iisnode handler.

Note the iisnode handler path is set to /index.js which seems to eliminate conflicts with client files of the same name.