From 9a3f7ff4120d7920a2d13809ff5ae78648c8a3d6 Mon Sep 17 00:00:00 2001 From: Bernice Wu <78245731+Bernice55231@users.noreply.github.com> Date: Fri, 16 Jan 2026 23:29:01 +0800 Subject: [PATCH] Polish HTML structure of the response in the res.redirect() function (#5167) * structure the DOM body * structure the DOM body * test: add html title to redirect test * fix: update HTML structure for include body and head tags * docs: improve HTML structure in res.redirect() responses for better browser compatibility --------- Co-authored-by: Sebastian Beltran --- History.md | 6 ++++++ lib/response.js | 3 ++- test/res.redirect.js | 8 ++++---- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/History.md b/History.md index facdf5b7..689c08a9 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,9 @@ +# Unreleased Changes + +## 🚀 Improvements + +- Improve HTML structure in `res.redirect()` responses when HTML format is accepted by adding ``, ``, and `<body>` tags for better browser compatibility - by [@Bernice55231](https://github.com/Bernice55231) in [#5167](https://github.com/expressjs/express/pull/5167) + 5.2.1 / 2025-12-01 ======================= diff --git a/lib/response.js b/lib/response.js index 7a2f0ecc..731afb78 100644 --- a/lib/response.js +++ b/lib/response.js @@ -850,7 +850,8 @@ res.redirect = function redirect(url) { html: function(){ var u = escapeHtml(address); - body = '<p>' + statuses.message[status] + '. Redirecting to ' + u + '</p>' + body = '<!DOCTYPE html><head><title>' + statuses.message[status] + '' + + '

' + statuses.message[status] + '. Redirecting to ' + u + '

' }, default: function(){ diff --git a/test/res.redirect.js b/test/res.redirect.js index 264e0f2b..8d2b164e 100644 --- a/test/res.redirect.js +++ b/test/res.redirect.js @@ -91,7 +91,7 @@ describe('res', function(){ .set('Accept', 'text/html') .expect('Content-Type', /html/) .expect('Location', 'http://google.com') - .expect(302, '

Found. Redirecting to http://google.com

', done) + .expect(302, 'Found

Found. Redirecting to http://google.com

', done) }) it('should escape the url', function(done){ @@ -107,7 +107,7 @@ describe('res', function(){ .set('Accept', 'text/html') .expect('Content-Type', /html/) .expect('Location', '%3Cla\'me%3E') - .expect(302, '

Found. Redirecting to %3Cla'me%3E

', done) + .expect(302, 'Found

Found. Redirecting to %3Cla'me%3E

', done) }) it('should not render evil javascript links in anchor href (prevent XSS)', function(done){ @@ -125,7 +125,7 @@ describe('res', function(){ .set('Accept', 'text/html') .expect('Content-Type', /html/) .expect('Location', encodedXss) - .expect(302, '

Found. Redirecting to ' + encodedXss +'

', done); + .expect(302, 'Found

Found. Redirecting to ' + encodedXss +'

', done); }); it('should include the redirect type', function(done){ @@ -140,7 +140,7 @@ describe('res', function(){ .set('Accept', 'text/html') .expect('Content-Type', /html/) .expect('Location', 'http://google.com') - .expect(301, '

Moved Permanently. Redirecting to http://google.com

', done); + .expect(301, 'Moved Permanently

Moved Permanently. Redirecting to http://google.com

', done); }) })