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('/')
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 trying to set up Snipcart for the first time. It seems pretty straightforward for the most part, but I'm running into some issues when I try to check out with the test payment card.
I'm working with just a vanilla front end, and Express on the back. I'm getting the same error every time:
A 'cart-confirmation' error occurred in Snipcart.
Reason: 'product-crawling-failed'
But the URL it's returning me in my console looks like it should be able to crawl for the product properly: https://myHerokuApp.herokuapp.com/shop/starry-night
<button class="snipcart-add-item"
data-item-id="starry-night"
data-item-price="79.99"
data-item-url="/shop/starry-night"
data-item-description="This is a sweet piece of art."
data-item-image="img/1.jpg"
data-item-name="The Starry Night">
Add to cart
</button>
I'm really confused at to what I'm doing wrong. Is there something I have to do with my express router? I've tried routing something like this just to see what would happen
router.get("/shop/:product", function (req, res, next) {
res.json({
"data-item-id": "starry-night",
"data-item-price": "79.99",
"data-item-url": "/shop/starry-night"
})
});
But that didn't make a difference.
I'm really hoping someone can spot what I'm doing wrong or point me in the right direction in the docs..
Thank you!
Attributes data-item-id and data-item-price are used with HTML crawler and are defined inside buy-button.
If you want to use JSON crawler, then you should return valid JSON with properties id and price. Also, price should be of type number. Change your backed like this:
router.get("/shop/:product", function (req, res, next) {
res.json({
"id": "starry-night",
"price": 79.99
})
});
Note: your server must be publicly available (not running in your localhost).
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.
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.
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.