'serving index.html on all the incoming http requests in node.js
I have a node server like this:
var express = require('express');
var fs = require('fs');
var path = require('path');
var root = fs.realpathSync('.');
var app = express();
app.configure(function () {
app.use(express.static(__dirname + '/./'));
app.use(app.router);
});
app.get('/*', function (req, res) {
res.sendfile(path.join(root, './index.html'))
});
/*app.get('/dashboard', function (req, res) {
res.sendfile(path.join(root, 'index.html'))
});*/
app.listen(3000);
console.log('Listening on port 3000');
On the frontend, I am using backbone routes to route the application modules using HTML History API. So its always a well formatted URL. The problem occurs when I refresh the page. It works fine in local node server but when I deploy the application on microsoft azure cloud, the refresh creates a problem and it says, it cannot find a resource.
Is there anything specific to azure that I need to configure to make it understand that it should serve index.html on new requests instead of looking up for the resource?
In apache, we use .htaccess to do so but I have no idea about how to do the same on azure cloud!
Solution 1:[1]
Found the solution:
You need to have a webconfig file in the root for this to work. Azure internally has nothing but IIS to serve the files. If you observe closely, server.js is of no use once you deploy the application. IIS takes the control to serve the index.html file and hence you need to do something in the IIS configuration. Here is the Web.config (case sensitive) file that you need to put in the application root:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="redirect all requests" stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" pattern="" ignoreCase="false" />
</conditions>
<action type="Rewrite" url="index.html" appendQueryString="true" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Solution 2:[2]
You might try just use()ing a general middleware instead of a method-specific route:
app.use(function (req, res) {
res.sendfile(path.join(root, './index.html'));
});
As far as I know, Express currently does not support method-specific middleware (e.g. app.get(function(req, res) { ... })).
Also on an unrelated note, var root = fs.realpathSync('.'); is unnecessary since the global __dirname should get you the same value.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | beNerd |
| Solution 2 | mscdex |
