In my express app I have a router listening to api/shorten/:
router.get('api/shorten/:longUrl', function(req, res, next) {
console.log(req.params.longUrl);
}
When I use something like:
http://localhost:3000/api/shorten/www.udemy.com
I get www.udemy.com which is what I expect.
But when I use:
http://localhost:3000/api/shorten/http://www.udemy.com
I get a 404 error.
I want to get http://www.udemy.com when I access req.params.parameter.
I'm not sure if you're still looking for a solution to this problem. Perhaps just in case someone else is trying to figure out the same thing, this is a simple solution to your problem:
app.get('/new/*', function(req, res) {
// Grab params that are attached on the end of the /new/ route
var url = req.params[0];
This way you don't have to sweat about any forward slashes being mistaken for routes or directories, it will grab everything after /new/.
You need to use encodeURIComponent in the client, and decodeURIComponent in the express server, this will encode all the not allowed characters from the url parameter like : and /
You need to escape as so:
escape("http://www.google.com")
Which returns:
"http%3A//www.google.com"
I just want to add that if you pass another params like ?param=some_param into your "url paramter" it will not show up in req.params[0].
Instead you can just use req.url property.
Related
I have a RESTFUL url design like this: GET /street/:streetName/house/:houseNumber or GET /street/:streetName/house/listings. As you can see, the :streetName and :houseNumber are resource names. I am trying to extract the static (common) parts from the url for some following logics which means I want to get /street/house and /street/house/listings (ablate all resources parts in the url).
I was trying to find a JS lib for this but didn't find one. Any pointers?
PS: I can do some string matching to achieve this like split by "/" then concat them and only care about the key words, so I can ignore all resource names. But this doesn't seem robust.
Assuming you have a route for each URL pattern, you can set an additional property req.staticParts in each middleware:
app.get("/street/:streetName/house/:houseNumber", function(req, res, next) {
req.staticParts = "/street/house";
...
})
...
.get("/street/:streetName/house/:houseNumber/listings", function(req, res, next) {
req.staticParts = "/street/house/listings";
...
})
.use(function(req, res) {
additionalLogic(req.staticParts);
});
This avoids string operations and is very explicit, therefore very robust.
Parsing the URL into staticParts without knowledge of the routes is problematic. For example, parsing the URL /street/house/25 based on keywords would lead to req.staticParts = "/street/house", but there is no matching route for it.
I'm looking for a method to catch these urls:
https://my.server.com/subsite
https://my.server.com/subsite.html
... but not these:
https://my.server.com/otherpath/subsite
https://my.server.com/other/path/subsite
What I got so far is this code - but obviously I'm also catching the urls I do not want to get (from above):
var express = require('express');
let app = express();
app.get(/\/subsite(?:\.html)?$/, function(req, res) {
})
I tried to fix my code by inserting com before the regex but this does not seems to be a working solution: /.*com\/subsite(?:\.html)?$/.
How can I get around this issue?
This worked for me.
app.get(/.*com\/subsite(?:\.html)?$/, function(req, res) {
})
Here is where i tested it: https://regex101.com/r/42lhKg/1
You don't need to use a Reg Ex object, this will work fine:
app.get("/subsite(.html)?", function(req, res) {
/*...*/
})
Matches any path beginning with "subsite" and with possibility of a .html
Your Regex is missing a the constraint to make subsite appear only in the begging ^:
/^\/subsite(?:\.html)?$/
witch is the same as using just the string:
"/subsite(.html)?"
that I mentioned in the other answer.
Don't forget that in express you only care about the path and query part of the url.
i know this is probably a silly question but I cant make it work, Im trying got match any route that does not match a word, api for example (exclude /api/*) but I cant make it work:
'/^(?=\/).(?!api\/).*$'
That doesn't work, then I tried this site: http://forbeslindesay.github.io/express-route-tester/ just to test I match / and give me this code:
/^\/?$/i
Then I tried at express but it didn't match /
Cannot GET /
Then I'm guessing theres something wrong with the code and not with the regex, do you have some hint?
app.get('/^\/?$/i', function(req, res) {
Using regex here doesn't seem like the right approach, it seems more like you'd want to use a parameterized route to handle protected routes.
app.get('/:directory/:page', function(req, res, next){
if(req.params.directory.toLowerCase() == 'api') res.redirect('/') //or whatever you want it to do
else {
//whatever your default action is
}
}
If you wanted to exclude several and handle them in the same way, you could make your if statement use regex:
if(/^(api|other_directory|whatever_else)$/i.test(req.params.directory)) res.redirect('/')
My MongoDB keys in person collection are like this:
TWITTER/12345678
GOOGLE/34567890
TWITTER/45678901
...
I define getPersonByKey route this way:
router.route('/getPersonByKey/:providerKey/:personKey').
get(function(req, res) { // get person by key
var key = req.params.providerKey + '/' + req.params.personKey;
// ...
}
);
Of course I'd prefer to be able to write something like this:
router.route('/getPersonByKey/:key').
get(function(req, res) { // get person by key
var key = req.params.key;
// ...
}
);
But this doesn't work, since GET http://localhost/getPersonByKey/TWITTER/12345678 of course results in a 404, since the parameter with the slash is interpreted as two distinct parameters...
Any idea?
Express internally uses path-to-regexp to do path matching.
As explained in the documentation, you can use a "Custom Match Parameter" by adding a regular expression wrapped in parenthesis after the parameter itself.
You can use the following path to get the result you need:
router.route('/getPersonByKey/:key([^/]+/[^/]+)').
get(function(req, res) { // get person by key
var key = req.params.key;
// ...
}
);
You can test and validate this or any other route here.
You can use this if your parameters has containing slashes in it
app.get('/getPersonByKey/:key(*)', function(req, res) { ... })
It works for me (at least in Express 4). In my case, I used parameters like ABC1/12345/6789(10).
Hopefully this useful.
app.get('/getPersonByKey/:key(*)', function(req, res) { ... })
This isn't working for me.
Swagger-ui will encode the path var before using it.
e.g. article/2159 will become article%2F2159.
When going directly with curl, it will not get encoded. the slash will remain a slash instead of %2F. And then the route is not matched.
Update: I'm on fastify. On express 4.X this works correctly.
I created a server with the express package, and I'm trying to read in a specific way the parameters from the URL.
The URL goes like this: http://127.0.0.1:8080/screen=3 (no '?' as the sign for parameters).
I need to save the number of the screen in a variable.
I tried this:
var express = require('express');
var app = express();
app.get('/screen:sceenNum', function (req, res) {
var temp = req.sceenNum;
res.send(temp); //for checking on the browser
});
I also tried this, but he must get '?' in the URL:
app.get('/', function(req, res) {
var screenNum = req.param('screen');
res.send(screenNum);
});
Can anyone please have a solution?
Thank you
You can access route/url parameters with the req.params object.
So a route like /screen:screenNum would accept urls like /screen3 and you would access 3 via req.params.screenNum.
Similarly, if you want to use the equals, just add that: /screen=:screenNum and the number is accessed the same.