I'm making a link shortener. I previously got a problem with the URLs but it got fixed with encoding the URL when putting it in the database and when redirecting it will decode the URL and redirect to it. The problem is that instead of redirecting me to like https://google.com it redirects me to mypage.com/google.com. I tried making a "debug" page when it just decode the URL and the URL is fine, with HTTPS:// and everything. The biggest problem is that it's all working on localhost but when I deploy it on my VPS it's not working. Only the debug page that decodes the URL works. I'm using express.js and mongoose. Here's my code for redirecting users:
app.get('/:shortUrl', async (req, res) => {
const shortUrl = await shorturl.findOne({ short: req.params.shortUrl })
if (shortUrl == null) {
res.send('URL not found!')
} else {
shortUrl.clicks
shortUrl.save()
res.redirect(decodeURIComponent(shortUrl.full))
}
})
CodePudding user response:
If the URL does not have a scheme, in a browser it assumes the scheme is HTTP, but in HTTP redirects the domain looks like a path with a dot. If you redirect to a path, it will redirect on the same domain, which explains the behavior with google.com
.
Try normalizing the URL or validating the full URL includes the scheme.
https://github.com/sindresorhus/normalize-url
https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_is_a_URL
CodePudding user response:
You can use the built in URL
object in order to make sure the redirect URL is full and valid:
res.redirect(new URL(decodeURIComponent(shortUrl.full)).toString())
If it is unable to make a valid URL from the input, it will throw, so it's better to wrap it in a try/catch.
try {
res.redirect(new URL(decodeURIComponent(shortUrl.full)).toString());
} catch (e) {
res.send('Invalid URL');
}