bro*_*ock 14 redirect node.js http-status-code-401 express
如果请求用户未经过身份验证,我想发送一个401的响应代码,但我还想在请求是HTML请求时重定向.我一直发现Express 4不允许这样:
res.status(401).redirect('/login')
Run Code Online (Sandbox Code Playgroud)
有谁知道处理这个的方法?这可能不是Express的限制,因为我要求基本上传递两个标题,但我不明白为什么会出现这种情况.我应该能够传递"未经过身份验证"的响应并将用户一次性重定向.
Jas*_*ust 19
发送回新位置标题的方法存在一些细微差别.
用redirect
:
app.get('/foobar', function (req, res) {
res.redirect(401, '/foo');
});
// Responds with
HTTP/1.1 401 Unauthorized
X-Powered-By: Express
Location: /foo
Vary: Accept
Content-Type: text/plain; charset=utf-8
Content-Length: 33
Date: Tue, 07 Apr 2015 01:25:17 GMT
Connection: keep-alive
Unauthorized. Redirecting to /foo
Run Code Online (Sandbox Code Playgroud)
app.get('/foobar', function (req, res) {
res.status(401).location('/foo').end();
});
// Responds with
HTTP/1.1 401 Unauthorized
X-Powered-By: Express
Location: /foo
Date: Tue, 07 Apr 2015 01:30:45 GMT
Connection: keep-alive
Transfer-Encoding: chunked
Run Code Online (Sandbox Code Playgroud)
使用原始(不正确)方法redirect
:
app.get('/foobar', function (req, res) {
res.status(401).redirect('/foo')();
});
// Responds with
HTTP/1.1 302 Moved Temporarily
X-Powered-By: Express
Location: /foo
Vary: Accept
Content-Type: text/plain; charset=utf-8
Content-Length: 38
Date: Tue, 07 Apr 2015 01:26:38 GMT
Connection: keep-alive
Moved Temporarily. Redirecting to /foo
Run Code Online (Sandbox Code Playgroud)
所以它看起来redirect
会放弃任何以前的状态代码并发送默认值(除非在方法调用中指定).由于在Express中使用了中间件,这是有道理的.如果您有一些全局中间件对所有请求进行预检查(例如检查正确的接受标头等),他们就不会知道重定向请求.但是,身份验证中间件会因此而知道覆盖任何先前的设置以正确设置它们.
更新:如下面的评论中所述,尽管Express可以发送带有Location头的4XX状态代码,但这并不意味着它是一个可接受的响应,请求客户端根据规范理解.事实上,除非状态代码是3XX值,否则大多数会忽略Location标头.
您当然可以Location: /login
在401页面旁边发送标题,但是,这是不明智的,大多数浏览器都不会遵循它,如rfc2616.
解决此问题的一种方法是<meta http-equiv="refresh" content="0; url=/login">
与您的401
页面一起提供服务:
res.set('Content-Type', 'text/html');
res.status(401).send('<!DOCTYPE html><html><head><meta http-equiv="refresh" content="0; url=/login"></head></html>`);
Run Code Online (Sandbox Code Playgroud)