Nodejs express 304/302 访问超时
Nodejs express 304/302 访问超时
express版本:express 3.4.8和express 4.9.5 环境:linux 64位 操作步骤:
-
安装express命令 #npm install -g express-generator;
-
建立网站基本结构 #express --ejs blog;
-
安装模块 #npm install;
-
将ip和port绑定到一个域名url。 访问地址url,页面正常加载,前端页面截图:
后台打印的日志截图:
-
刷新页面 页面一直加载不出来,直到超时,前端网页截图:
后台打印的日志截图:
此时后台一直卡在304状态,没有发送应答给浏览器,然后浏览器过一段时间显示超时。
-
禁止掉etag后不会出现此问题(每次请求都返回200,不再是304)。 app.disable(‘etag’);
-
禁止掉etag后,只要express应答出现304或者重定向(redirect)302都会出现上述问题。
哪位大神遇到过这个问题,求解答。
- linux服务器的问题?
- express的配置问题?
- express本来就存在这个问题?
Node.js Express 304/302 访问超时
环境与版本
- Express 版本: 3.4.8 和 4.9.5
- 操作系统: Linux 64位
操作步骤
-
安装 Express
npm install -g express-generator
-
创建项目结构
express --ejs blog cd blog npm install
-
启动应用
node app.js
访问
http://your-domain:3000
,页面可以正常加载。-
前端页面截图:
-
后台日志截图:
-
-
刷新页面 页面长时间无响应,最终超时。
-
前端页面截图:
-
后台日志截图:
-
问题分析
-
304 Not Modified:
- 当客户端请求资源时,如果资源未修改,服务器会返回304状态码,这表示客户端的缓存有效。然而,在某些情况下,这种机制会导致页面长时间无响应。
-
302 Found:
- 重定向302也会导致同样的问题,客户端不断尝试新的URL,而服务器端没有及时响应。
解决方案
-
禁用 ETag
- ETag 是一种用于验证资源是否改变的机制,禁用它可以避免304状态码。
app.disable('etag');
-
处理重定向
- 如果需要重定向,确保在重定向之前进行适当的处理,例如检查某些条件。
app.get('/some-route', function(req, res) { // 检查条件 if (condition) { res.redirect('/new-url'); } else { res.send('OK'); } });
可能的原因
- Linux 服务器问题: 可能是服务器配置或网络问题。
- Express 配置问题: ETag 或者重定向配置不当。
- Express 本身问题: 在某些版本中可能存在已知问题。
希望这些信息能够帮助你解决问题。如果你有更多细节或错误日志,可以进一步排查。
关注一下
好难的感觉…
重现了一下,无论是Firefox还是Chrome直接访问http://ip_address:port
都没问题。你是用域名访问的,直接用IP地址访问,检查是否还出现这个问题。
下面是测试用到的设置:
- Ubuntu 14.04 64bit
- node.js 0.10.29
- npm 1.4.14
- express 4.9.5
根据你的描述,该问题可能与Express框架中的缓存机制有关。304 Not Modified
状态码表示资源未被修改,通常用于HTTP缓存。当客户端请求资源且缓存有效时,服务器会返回 304
状态码,并让客户端从本地缓存中读取数据。
解释
-
问题根源:当你设置
etag
后,Express会自动添加一个etag
头信息到响应中。如果客户端请求同一个资源时,它会带上一个if-none-match
请求头。如果服务器发现资源未被修改,则返回304
状态码。此时,客户端应该从缓存中获取资源,而不是等待服务器重新发送资源。 -
实际现象:你在禁用了
etag
后,问题消失。说明问题确实与etag
有关。如果你希望避免304
或302
状态码导致的访问超时问题,可以考虑以下几种方法:
方法一:禁用 etag
const express = require('express');
const app = express();
// 禁用 etag
app.disable('etag');
// 其他中间件和路由配置
方法二:确保路由处理函数能够正确处理 304
状态
确保你的路由处理函数能快速返回,即使返回 304
状态码。
app.get('/example', (req, res) => {
// 假设 'data' 是一个资源对象
const data = getData(req.params.id);
if (data.isModifiedSince(req)) {
res.status(200).send(data.content);
} else {
res.status(304).end();
}
});
方法三:检查客户端的 if-modified-since
和 if-none-match
请求头
确保客户端正确设置了这些请求头,以便服务器能够正确判断是否需要返回 304
状态码。
结论
该问题可能是由于客户端未能正确处理 304
状态码,或者Express的 etag
配置导致的问题。通过禁用 etag
或者确保路由处理函数能够快速返回,可以解决该问题。如果以上方法都不能解决问题,建议进一步排查客户端和服务器之间的交互细节。