ExpressJS incorrectly rewriting paths when navigating directories
I've run into a maddeningly inconsistent issue with Express in a Node application where I am not able to correctly navigate through the built-in directory rendering due to a URL rewrite. It's easier to explain with code:
var express = require('express');
var app = express.createServer();
app.use("/public", express.static("/web/content"));
app.use("/public", express.directory(开发者_StackOverflow社区"/web/content"));
app.listen(8888);
Using the uber-simple express server above the contents of /web/content
are displayed as a list of links when you navigate to localhost:8888/public
. So, for example:
..
index.html
header.jpg
js (folder)
css (folder)
From there if I click on index.html
or header.jpg
they display correctly, but clicking on the either folder will navigate to (for example) localhost:8888/js
, even though the link clearly leads to localhost:8888/public/js
. Upon further inpection it's revealed that the request is sent out for the right path (/public/js
), but the server returns a 301 - Moved Permanently
response that then redirects the browser to /js
, which proceeds to display an error page because the content cannot be found. (No, really?)
Attempts to request a specific file beneath these folders (ie: localhost:8888/public/js/main.js
) works fine and does not have the same issue.
The maddening part is that it was doing this on my dev box for a while and then simply... stopped. Not sure why. When attempting to deploy, however, the production server started having the same issue even though I can no longer reproduce it in my dev environment. Does anyone know why Express seems so intent on rewriting my URLs to the wrong thing?
Turns out the answer was pretty simple, and I only missed it because of my browser cache. After digging through the Express (well, technically Connect) code and sprinkling it liberally with console.log(), I traced it down to some code in the static middleware that was detecting that the directory contained an index.html file and was attempting to display that instead. Somehow that code got the wrong path, and the invalid redirect happened.
The real problem, though, was that the static handler was acting before the directory middleware could, which is a direct result of the order in which the middleware was declared. As such simply flipping the middleware declaration like so:
app.use("/public", express.directory("/web/content"));
app.use("/public", express.static("/web/content"));
fixed the issue.
Now, I had actually tried this before but did not realize that the 301 that I was sent previously had been cached, and so the browser was redirecting me before even touching the server. After flipping the order AND emptying my cache, I was able to navigate thde directory structure correctly.
Sigh If I had a dollar for every "bug" I've encountered caused by browser cache...
精彩评论