ExpressJS 在导航目录时错误地重写路径
我在 Node 应用程序中遇到了与 Express 极其不一致的问题,由于 URL 重写,我无法正确导航内置目录呈现。用代码解释更容易:
var express = require('express');
var app = express.createServer();
app.use("/public", express.static("/web/content"));
app.use("/public", express.directory("/web/content"));
app.listen(8888);
使用上面的 uber-simple Express 服务器,当您导航到 localhost:8888/public
时,/web/content
的内容将显示为链接列表代码>.因此,例如:
..
index.html
header.jpg
js (folder)
css (folder)
从那里,如果我单击 index.html
或 header.jpg
,它们会正确显示,但单击任一文件夹将导航到(例如)< code>localhost:8888/js,即使该链接明确指向 localhost:8888/public/js
。进一步检查后发现,请求是发送到正确的路径 (/public/js
),但服务器返回 301 - Moved Permanently
响应,然后重定向该请求浏览器访问 /js
,由于找不到内容,因此会显示错误页面。 (不,真的吗?)
尝试请求这些文件夹下的特定文件(即:localhost:8888/public/js/main.js
)工作正常,并且没有相同的问题。
令人抓狂的是,它在我的开发盒上这样做了一段时间,然后就……停止了。不知道为什么。然而,当尝试部署时,生产服务器开始出现相同的问题,尽管我无法再在我的开发环境中重现它。有谁知道为什么 Express 似乎如此热衷于将我的 URL 重写为错误的内容?
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("/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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
事实证明答案非常简单,我只是因为浏览器缓存而错过了它。在深入研究了 Express(嗯,技术上是 Connect)代码并使用 console.log() 进行了大量的操作之后,我追踪到静态中间件中的一些代码,该代码检测到该目录包含一个 index.html 文件并试图显示它。不知何故,该代码获得了错误的路径,并且发生了无效的重定向。
然而,真正的问题是静态处理程序在目录中间件之前起作用,这是中间件声明顺序的直接结果。因此,只需像这样翻转中间件声明即可:
解决了问题。
现在,我之前实际上已经尝试过此操作,但没有意识到之前发送的 301 已被缓存,因此浏览器甚至在接触服务器之前就重定向了我。翻转顺序并清空缓存后,我能够正确导航目录结构。
叹息如果我遇到的每个由浏览器缓存引起的“错误”都能得到一美元......
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:
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...