URL as parameter in Express - node.js

Using Node.js with Express, how do I accept a URL as a parameter?
i.e http://example.com/site/http%3A%2F%2Fgoogle.com
I have the following handler
app.get('/site/:dest', function (req, res, next) {
res.end('URL = ' + req.params.dest);
});
Rather than getting the expected response i get a 404:
The requested URL /site/http://www.google.com was not found on this
server.
If i request example.com/site/hello it works fine, but not for passing a URL. I assume its the forward slashes escaping that's causing the problem.
Is there a correct way to do this?

It's worked for me
app.get('/site/*', function (req, res, next) {
res.end('URL = ' + req.params[0]);
});

You need to encode your parameter's URL. You will have a lot of issues if you just send the URL as a param.
Best way is to url encode the param and on your nodejs side you will need to url decode
Example:
https://www.google.com will be https%3A%2F%2Fwww.google.com

Here is a workaround:
Changed the routing and now using req.query
app.get('/', function (req, res, next) {
res.end('URL = ' + req.query['site']);
});
Now, http://example.com/?site=http%3A%2F%2Fexample.com%2F%3Fhello%3Dworld%26foo%3Dbar works as expected.

Related

Query String missing when redirecting with expressjs

I have the following express js route which helps in redirecting to the given URL.
app.get("/", async (req, res) => {
const url = req.query.url;
res.redirect(url);
});
It's working fine. But the problem is, somehow the passed query strings is getting cut off for no reason.
Example:
This is what I'm actually passing.
http://localhost:3000/?url=https://google.com/?abc=123&def=456&aaa=098
After redirecting whatever after the first query string goes missing.
It's appearing like this.
https://google.com/?abc=123
Not sure why &def=456&aaa=098 goes missing.
Use the encodeURIComponent and decodeURIComponent functions.
For example:
app.get("/", async (req, res) => {
const url = req.query.url;
res.redirect(decodeURIComponent(url));
});
Note that the url parameter must be encoded in the actual URL.
Your URL should look something like this:
http://localhost:3000/?url=https://google.com/%3Fabc%3D123%26def%3D456%26aaa%3D098

nodejs get req.param from route

I am trying to get the url parameter of an url request from the front in my nodejs backend.
fetch(`http://localhost:9000/sent/5768797675645657`)
Here is my app.js file :
app.use('/sent/:id', require('./routes/sent'));
And my /routes/sent.js file :
router.get('/', function(req, res) {
console.log(req.params)
})
How can I get the console.log(req.params) to work?
So, app.use accepts two parameters: the portion of the URL, and a callback function.
In order to your app works, you've to change the /routes/sent.js and make it exports the function, so it can be used when you're requiring it.
Just change it to
module.exports = function (req, res) {
console.log(req.params)
}
and you're ready to go!

first portion of route url is not included

I have a route where I built two GET APIs. I would like one to redirect from /download to /zip all while passing a parameter. The problem is I am getting a 404 for some reason the routes url is not being included in the redirect()
Here are the APIs.
// respond with xml from from static folder
router.get('/zip/:id', function (req, res) {
fileName = req.params.id
});
router.get('/download', function (req, res, next) {
var id = req.query.id
res.redirect('/zip?id='+ id);
});
module.exports = router;
I get a 404 when testing the URL:
localhost:8000/rest/pluto/v1/plugin/download?id=networktool
I am thinking it might be how I have the middleware setup but not real sure. I'm still new to node/express.
You are redirecting to a route that isn't actually defined. With your /zip/:id route definition:
router.get('/zip/:id', function (req, res) {
var fileName = req.params.id
});
The way that is defined, you have to have id information in the URL itself, so while the following routes would work:
/zip/networktool
/zip/1234
these routes would not:
/zip
/zip?id=networktool
/zip?id=1234
because Express is looking for the id to be built into the route itself. So you can do one of two things. You can either change your redirect to:
router.get('/download', function (req, res, next) {
res.redirect('/zip/'+ req.query.id);
});
or, you can modify your /zip route to make the id parameter optional with ?:
router.get('/zip/:id?', function (req, res) {
var fileName = (req.params.id) ? req.params.id : req.query.id;
});
I would recommend the first option, as the latter optional parameter only makes your zip route more complicated and require extra handling of whether id is actually passed to your route.
The path /zip/:id is expecting a path parameter not a query parameter.
You should redirect like this
res.redirect('/zip/'+ id);

Resolve URL with info from URL parameters

I've been thrown at a Node.js project at work and I'm not a Node developer. My first task is to resolve urls to stores from a URL parameter. Here's what needs to happen:
The original URL contains the URL parameter "siteName" as here:
https://example.com/s/Store/?siteName=SLUG
The above url with parameter would then resolve to
https://example.com/s/Store/SLUG
This project is running on Express ^4.3.0.
I've been diving into the Node docs but I'm not sure even where to start.
I would suggest you look into Express
The solution to your problem is easy. Firstly, you'd need to establish a middleware to listen to requests for /s/Stores route. Then parse the query params and get the value for the siteName key. Finally use the res.redirect method to run the logic for /s/Store/SLUG route.
The solution would look something like
app.get('/s/Stores', (req, res, next) => {
const query = req.query;
const siteName = query.siteName;
res.redirect('/s/Stores/' + siteName);
});
app.get('/s/Stores/:siteName', (req, res, next) => {
const siteName = req.params.siteName;
if (siteName === 'SLUG') {
// do something
}
// do something else
});
Assuming Store route is the page you want to see with parameters, if you are using url query parameters, use first example and it matches your first question.
If you are trying to get url parameters without query, use second example.
//https://example.com/s/Store/?siteName=SLUG
app.get('/Store', function(req, res){
let siteName = req.query.siteName,
});
//https://example.com/s/Store/SLUG/
app.get('/Store/:slug', function (req, res) {
let slug = req.params.slug,
});

Arabic URL route using express web framework?

I have a problem getting express to render a page using an arabic url route:
app.get('/شقق-في-لندن', function(req, res){
res.render('apartments');
});
when I try access this using the browser localhost:5000/شقق-في-لندن i get an error saying not found.
Cannot GET /%D8%B4%D9%82%D9%82-%D9%81%D9%8A-%D9%84%D9%86%D8%AF%D9%86
You have two options:
a) Write a middleware (executing before routing) that URL-decodes the UTF8 characters in URL and updates req.url
Advantage: Any subsequent middleware you write can refer to the original UTF-8 characters
Crude example:
app.use(function(req, res, next) {
req.url = decodeURI(req.url);
next();
});
[OR]
b) Change route(s) to match the URL-encoded versions like so
app.get('/%D8%B4%D9%82%D9%82-%D9%81%D9%8A-%D9%84%D9%86%D8%AF%D9%86', function(req, res){
res.render('apartments');
});
or more elegantly:
app.get('/'+encodeURIComponent('شقق-في-لندن'), function(req, res){
res.render('apartments');
});
You could use request params and check for the url like the following
app.get('/:arabic_url', function(req, res , next ){
if(req.params.arabic_url !== 'شقق-في-لندن') {
return next();
}
res.render('apartments');
});
I found A problem with my current implementation and I recommend the way #Vasan because in my impementation the order of your routes will cause an error , unexpected behaviour and redundancy.
Here is the right solution
app.get('/' + encodeURIComponent('شقق-في-لندن') , function(req, res){
res.render('apartments');
});

Resources