Node.js route regex - node.js

i want a route url to be like this
http://localhost:3000/api/uploader/:path
The moment is that path can be '' => http://localhost:3000/uploader/ or string containing slashes like this aaa/bbb/ccc => http://localhost:3000/api/uploader/aaa/bbb/ccc
I wrote something like this for empty case
http://localhost:3000/api/uploader/:path?
How can I write regex for many slashes, so the req.params === /aaa/bbb/ccc ?

I'll assume you're using express and answer below.
What you're looking for is the * wildcard.
Try this and check it out:
router.get('/uploader/?*', function(req, res, next) {
res.send(req.originalUrl);
});
You should see the request url back to you so you can confirm.
Edit: I'm changing the wildcard with the question mark to accept baseUrl too***
Tell me if anything else, but that should do it. I hope this helps you out.

Related

Why regex path in express route does not capture query strings?

app.get(/\/example\/(.+)/, (req, res) => {
const url=req.params[0]
})
The URL "/example/test.com?a=1" matches the given regex route, but the capture group does not capture the query string. I know I can obtain the query params using req.query.
But the capture group should have captured the entire test.com?a=1, but it only captures test.com.
I don't understand why this is happening. Am I missing something?
Route strings, whether regex or simple, don't capture query strings (after the ?). You use req.query for that, as you know
They capture parts of the URL path. Therefore, if your url were
https://example.com/a/1
you could write a regex path to capture the 1.

How to ignore specific files to be loaded when I use route parameters in Express

When I make a GET request with route parameters in express with mongoose like the following code, I sometimes see that the browser tries to load some unexpected files such as favicon.ico, robots.txt, humans.txt, sitemap.xml, ads.txt, etc., and 404 error shows up in the browser console.
app.get("/:userId", ...);
By refering to this Q&A, I figured out that if I don't use the route parameters right after the root route like the following code, it doesn't happen.
app.get("/user/:userId", ...);
In the same Q&A, however, there seem to be another way that uses req.url to ignore those unexpected files to be loaded, but it isn't explained in detail.
How do you do that?
All that's meant in that other answer is that you could examine req.url in your route handler and make sure it is not a known special name. In this specific case, it's probably simpler to use req.params.userId instead of req.url, but you could also use req.url in the same way.
const specials = new Set(["favicon.ico", "robots.txt", "humans.txt", "sitemap.xml", "ads.txt"]);
app.get("/:userId", (res, res, next) => {
// if it's a special URL, then skip it here
if (specials.has(req.params.userId)) {
next();
return;
}
// process your route here
});
Personally, I wouldn't recommend this solution because it presupposes a perfect knowledge of all possible special filenames. I don't use a top level wildcards ever because they ruin the ability to use your server for anything else.

how to fetch req.params whatever it was

I'm working on a url shortener api. The problem i'm facing is that if I pass a parameter like https://www.youtube.com/watch?v=8aGhZQkoFbQ then req.params.url will only be equal to https://www.youtube.com/watch. I've looked a lot on stackoverflow and all the answers are similar but not what I'm looking for.
I want to parse the url parameter and get the characters it contains.
This is the URI i'm using right now
router.route('/add/:url(*)')
You can try something like this:
app.get(/[/]add[/].*/, function (req, res) {
var uri = req.originalUrl.replace(/^[/][^/]*[/]*/, '');
console.log(uri);
res.end();
});
Maybe you're wanting the query part of the URL? Take a look at req.query docs (and other parts of the request) and read about the parts of the URI or more formal definitions on wikipedia. Having the correct names will help you understand the Express.js docs.
From express.js docs:
// GET /search?q=tobi+ferret
req.query.q
// => "tobi ferret"
From wikipedia:
scheme:[//[user:password#]host[:port]][/]path[?query][#fragment]

URL parameters before the domain

I have a question about routing and urls in general. My question regards parameters or queries in the url before the domain itself. For example:
http://param.example.com/
I ask this question because I am using ExpressJS and you only define your routes after the domain itself like:
http://example.com/yourRoute
Which would be added to the end of the url. What I want is to be able to store parameters inbefore the domain itself.
Thank you in advance!
FYI
I do know how to use parameters and queries, I just don't know how I would go about to insert them before the domain.
You can create an if statement which can look at the sub-domain through the express req.headers.host variable which contains the domain of the request. For example:
-- google.com/anything/another
req.headers.host => "google.com"
-- docs.google.com/anything/
req.headers.host => "docs.google.com"
So working off this in your route you can call Next() if the request doesn't match the form you want.
router.get('/', function(req, res, next) {
if (req.headers.host == "sub.google.com") {
//Code for res goes here
} else {
//Moves on to next route option b/c it didn't match
next();
}
});
This can be expanded on a lot! Including the fact that many packages have been created to accomplish this (eg. subdomain) Disclaimer you may need to account for the use of www. with some urls.
Maybe this vhost middleware is useful for your situation: https://github.com/expressjs/vhost#using-with-connect-for-user-subdomains
Otherwise a similar approach would work: create a middleware function that parses the url and stores the extracted value in an attribute of the request.
So I would use something like
router.get('/myRoute', function(req, res,next) {
req.headers.host == ":param.localhost.com"
//rest of code
}
I think I understand what you are saying, but I will do some testing and some further reading upon the headers of my request.
EDIT: Right now it seems like an unnecessary hassle to continue with this because I am also working with React-router at the moment. So for the time being I am just going to use my params after the /.
I thank you for your time and your answers. Have a nice day!

How can I allow slashes in my Express routes?

I'm attempting to implement permalinks, in the form /2013/02/16/title-with-hyphens. I'd like to use route parameters. If I try the following route:
app.get('/:href', function(req, res) { });
...then I get a 404, presumably because Express is only looking for one parameter, and thinks that there are 4.
I can work around it with /:y/:m/:d/:t, but this forces my permalinks to be of that form permanently.
How do I get route parameters to include slashes?
It seems that app.get("/:href(*)", ...) works fine (at least in Express 4). You will get your parameter value in req.params.href.
It will also be fired by / route, which is probably not what you want. You can avoid it by setting app.get('/', ...) elsewhere in your app or explicitly checking for an empty string.
Use a regular expression instead of a string.
app.get(/^\/(.+)/, function(req, res) {
var href = req.params[0]; // regexp's numbered capture group
});
Note that you cannot use the string syntax (app.get('/:href(.+)')) because Express only allows a small subset of regular expressions in route strings, and it uses those regular expressions as a conditional check for that particular component of the route. It does not capture the matched content in the conditional, nor does it allow you to match across components (parts of the URL separated by slashes).
For example:
app.get('/:compa([0-9])/:compb([a-z]/')
This route only matches if the first component (compa) is a single digit, and the second component (compb) is a single letter a-z.
'/:href(.+)' says "match the first component only if the content is anything", which doesn't make much sense; that's the default behavior anyway. Additionally, if you examine the source, you'll see that Express is actually forcing the dot in that conditional to be literal.
For example, app.get('/:href(.+)') actually compiles into:
/^\/(?:(\.+))\/?$/i
Notice that your . was escaped, so this route will only match one or more periods.
You can do this with regex routing
app.get('/:href(\d+\/\d+\/\d+\/*)', function(req, res) { });
I don't know if the regex is right, but you get the idea
EDIT:
I don't think the above works, but this does
app.get(/^\/(\d+)\/(\d+)\/(\d+)\/(.*)/, function(req, res) { });
Going to http://localhost:3000/2012/08/05/hello-i-must-be yeilds req.params = [ '2012', '08', '05', 'hello-i-must-be' ]
You can use this if your parameters has include slashes in it
app.get('/:href(*)', function(req, res) { ... })
It works for me. In my case, I used parameters like ABC1/12345/6789(10).
Hopefully this useful.

Resources