Node/Express - How to change default root URL - node.js

I have a single page application I am working on. The goal is to have the main root route be something other than www.website.com. Something like www.website.com/cool-page This is for SEO purposes. I am not sure if it is best practice or even possible.
Thus far I've been able to change the URL on load using this:
// root route
router.get('*', function(req, res) {
res.redirect('/cool-page');
});
This gives me an error that the page redirected you too many times.
Any advice on this?

Your routing definition looks like it would redirect every request to URLs within the root URL, not just those going to the root URL itself. So it will redirect even the redirected requests going to /cool-page, forming an infinite loop. Try using router.get('/', ... ) instead, I think that would redirect only requests made to the root url,

Related

using relative URLs in nodejs express

I am using express routing like:
router.get('/test', function(req, res, next) {
if (user logged in)
res.render('test');
else res.redirect('login')
I'm rendering an EJS template file that has CSS links in it and URLs that are
relative to this.
So you might see stuff like this in the test.ejs template:
<link href = "../stylesheets/bootstrap.min.css" rel = "stylesheet">
blee
The problem I encounter is that this route handler accepts URLs that look like
/test and /test/ - This second URL causes my relative URLs to form incorrect absolute URLs.
So if the URLs in my app (when deployed to production using Apache to forward to myapp) are:
example.com/myapp/test
I expect that the CSS be found at
example.com/myapp/stylesheets/bootstrap.min.css
and the blee URL found at
example.com/myapp/blee
and the redirect should go to
example.com/myapp/login
This works as long as the URL coming into the handler is /test
If, however, it is /test/ , the handler accepts it BUT the relative URLs formed are all incorrect.
My dev environment is different from my deploy environment so I can't code full URLs to things because its a longer path before /test. Relative URLS just make better sense.
I've been told not to worry about the URL /test/ coming in as long as my app doesn't create it. But sometimes a user types something into the location box and it sucks that if they type this, it lands inside this handler and generates a broken page.

Redirect POST to POST using Express JS routes

So I have a landing page ('/'). On this page is a login form for a username and password with a submit button. I have the app.get that loads the page and an app.post to receive the parameters of the form. However, my intention is to have an app.post('/login', function (req, res){ //logic}); There is no /login route or page to load, this would simply house the logic for the login itself (validation of the username, etc.) Is there an easy way to get the post from '/' to redirect into the post for /login without it trying to load the /login page, which does not exist?
I'm not sure if I understand your question correctly. As I understand you want your POST request to / get redirected to POST requests to /login which can be tricky.
Usually you do redirects by sending either 301 Moved Permanently or 302 Found HTTP status code. Both of them usually work in practice as if it was 303 See Other and a GET request is made. See List of HTTP status codes on Wikipedia:
This is an example of industry practice contradicting the standard.
The HTTP/1.0 specification (RFC 1945) required the client to perform a
temporary redirect (the original describing phrase was "Moved
Temporarily"), but popular browsers implemented 302 with the
functionality of a 303 See Other. Therefore, HTTP/1.1 added status
codes 303 and 307 to distinguish between the two behaviours.
However, some Web applications and frameworks use the 302 status code
as if it were the 303.
There is a 307 Temporary Redirect (since HTTP/1.1) created to address this issue that is not allowed to change the HTTP method - so a redirect from POST should still be POST - see Wikipedia:
In this case, the request should be repeated with another URI;
however, future requests should still use the original URI. In
contrast to how 302 was historically implemented, the request method
is not allowed to be changed when reissuing the original request. For
example, a POST request should be repeated using another POST
request.
As far as I know browsers should warn users before following such redirects. I don't know how that works in practice. I wouldn't rely on that since it can be annoying to users at best or even not work at all.
My suggestion would be to either change this:
app.post('/login', function (req, res) {
// logic
});
to this:
function loginHandler(req, res) {
// logic
}
app.post('/login', loginHandler);
app.post('/', loginHandler);
or something like this, using regular expressions:
app.post(/^\/(?:login)?$/, function (req, res) {
// logic
});
That way instead of a redirect the same handler will be used for both of those routes. It would be both faster and more robust because that way you don't rely on the redirect working as you want - there is no redirect at all.

Unable to access ExpressJS route via href link

I'm not sure if this is a security feature or if I'm missing something obvious. I need to access one of my ExpressJS routes directly via a standard link on the page.
If I type the URL in to my browser location bar, I get the desired result. However, if I put that exact URL in a standard link on one of the pages on the site, the route never gets hit.
EDIT: Even if I pull this out of the router and add directly to app.js I get the same results. I'm simply trying to use Passport's Facebook authentication. The first route looks like this:
router.get('/login/facebook', function(req, res, next) {
passport.authenticate('facebook')(req, res, next);
});
I realize the req function wrapper is not needed, I was using it for debugging so I could see when the route gets called.
If I set a breakpoint there, it works fine if I just type the "/api/login/facebook" URL into my browser, but if I put the exact URL in a link on the page, the route never gets hit.
It turns out this was caused by Angular's routing mechanism intercepting the links. I found the solution here:
How to get Angular UI Router to respect "non-routed" URLs

Send user to new url from node.js

I'm working on a Node.js app. When a user hits the main url, a database call will be made. This database call returns a URL path. I'm trying to understand how to send the user to that new URL from my Node app. That URL is local to the app itself. Everything I see involves a 301. I'm not sure if that what I really want though. Currently, my code looks like this:
getUserUrl: function (req, res) {
var url = getNewUrl();
res.status(200).send();
}
This only confirms the request to getUserUrl was ok. However, it doesn't actually send the user to url. How do I redirect the user to url?
THank you!
I don't know why you say a 301 isn't what you want, because that is definitely one of the options you have available to you.
Typically, a 301 status code is used for a permanent redirect. That is, a request for a certain URL will be considered to always redirect to where you send that user, and browsers and proxies can cache this redirection indefinitely.
A 302 status code is a temporary redirect. Subsequent requests for the same URL will come to your server (as long as you don't enable caching for it), allowing you to continue to redirect or not.
In either case, you need the status code along with a Location: header to tell the user agent where to go.
res.setHeader('Location', 'http://example.com');
res.statusCode = 302;
res.end();
These days you can also use 307 and 308 status codes for redirection. They are more explicitly defined in the RFCs and provide roughly the same functionality as 301 and 302.

Catch-all root level routing in Express.js: considerations and reserving possible routes for future use?

I'm using Express.js (3.0) to develop a Node web app; I'd like to have clean URLs for both user profiles:
domain.com/username
as well as for pages each user creates and shares:
domain.com/username/pagename
I really prefer the clean URLs to using something like domain.com/profile/username or domain.com/pages/username/pagename.
The current route configuration for our development is bootstrapped like so:
app.get('/', content.home);
app.get('/about', content.about);
app.get('/signup', users.signup);
app.get('/login', users.login);
app.get('/:user', users.profile);
app.get('/:user/:userpage', userpage.render);
The last two being the catch all routes. Now this works fine, but I'm not sure if it's a bad design or implementation.
More importantly, I'd like to reserve a 100 or so page names for future use, like 'contact', 'careers', 'cancels', 'pricing', etc. I don't plan to launch with these pages, but I'm wondering if I can create a route file that captures these requests and sends them to a placeholder page, rather than them being evaluated as a user profile or user generated page.
I can obviously prevent those usernames from being created, but there's got to be a creative approach for the routing as well, and understand any other considerations when using catch-all root level routing-- this can cause an unwieldily amount of DB strain due to the user and page look ups for non-existing objects or pages.
What you could do is something like the following snippet of code. It's in coffee-script, but the general theory is the same.
placeholder = (req, res, next) ->
res.render 'placeholder'
reserved = ['/contact','/careers','/cancels','/pricing']
each page in reserved
app.get page, placeholder
app.get '/:user', ....
If you decide you want to add an extra placeholder page, just add it into that array and restart the application.
I'm not 100% sure, but if you put all your routes above the :user then a user who registered your pagename would not get displayed.

Resources