Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTML in the res.redirect() method is missing a DOCTYPE and <title> element #5058

Open
SaekiTominaga opened this issue Dec 8, 2022 · 4 comments

Comments

@SaekiTominaga
Copy link

SaekiTominaga commented Dec 8, 2022

The response body of a redirect via the res.redirect() method will be <p>${statuses.message[status]} Redirecting to <a href="${url}">${url}</a></p>, which is invalid HTML without a DOCTYPE and <title> element.
In particular, the absence of a <title> element is detrimental to the user.

RFC 9110, 15.4. Redirection 3xx, states that the user agent behavior when the Location header field is set with status code 3xx is "the user agent MAY automatically redirect its request to the URI".
Note that it is MAY.

And in fact, depending on the user's environment, automatic redirection may not occur and the contents of the response body may be displayed on the screen.
In the old days, there was an option to disable redirects in Presto Opera's advanced settings.
Even now, when Android Firefox redirects to an app-linked URL with 3xx, the app is automatically launched, but the browser screen still displays the 3xx response body.

Therefore, it would be desirable to set the DOCTYPE and <title> element even for 3xx screens.

Improvement plan

body = '<p>' + statuses.message[status] + '. Redirecting to <a href="' + u + '">' + u + '</a></p>'

body = '<!DOCTYPE html><title>' + statuses.message[status] + '</title><p>' + statuses.message[status] + '. Redirecting to <a href="' + u + '">' + u + '</a></p>'
@sheplu
Copy link
Member

sheplu commented Dec 14, 2022

Not sure that this is something standard. What is being done by others frameworks / languages?
If needed - we should provide a complete and valid HTML part (which would include header/body) - but again this is a nice to have as the RFC doesn't precise that we need to send a value.

@SaekiTominaga
Copy link
Author

I am not familiar with the status of other Node.js frameworks, but the situation of popular web server software is as follows.

Apache 2.4

ServerSignature Off
Redirect permanent / https://example.com/
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="https://example.com/">here</a>.</p>
</body></html>

nginx 1.23

location / {
    rewrite ^ https://example.com/ permanent;
}
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.23.3</center>
</body>
</html>

@dougwilson
Copy link
Contributor

Hi @SaekiTominaga thank you for that! Those seem to have a lot more parts than your initial recommendation.

So in order to understand the issue, can you provide us the details of what clients are not able to render the response from express? This will better help guide the conversation by having the information regarding which clients/browsers are having an issue with the response from Express and thus we can work to make sure and validate that any changes made will resolve the issue.

@SaekiTominaga
Copy link
Author

Hi, @dougwilson !

Currently, most browsers automatically redirect when a Location header is present in a 3xx, so the user has very limited exposure to the response HTML.
As noted in the first comment, I know this occurs in Android Firefox.

  1. Install Firefox and the Twitter application on Android device.
  2. Put the redirection process in app.js. (Code#1)
  3. Access http://localhost:3000/twitter with Firefox.
  4. The Twitter application will automatically launch.
  5. When you return to the Firefox application, the redirect screen will be displayed. (Image#2)
  6. Here, the <title> element is not present, so the tab displays the URL as is. If <title> element is set, the tab will display its value. (Image#3)

Code#1 (app.js)

app.get('/twitter', (req, res) => {
	res.redirect(301, 'https://twitter.com/');
});

Image#2
Redirect message is displayed on the browser screen

Image#3
A side-by-side view of the redirect screen and Google page in a browser

* The redirect process itself works fine. This is just a measure to prevent user confusion by displaying the page title in the browser tab by adding the <title> element.
* According to the HTML specification, the <title> element is required, with a few exceptions. Therefore, regardless of how Android Firefox works, even redirect screens should include a <title> element.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants