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);
Related
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!
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,
});
I have a server in express and it uses an external api. I would like for each request to that api ('/api/*'), that it appends a query param in the url without to write it for each requests.
app.use(function(req, res) {
req.query.key = process.env.APIKEY;
});
I tried something like that but it doesn't work.
I thought of doing something like :
app.get('/api/stuff', addApiKey, api.stuff);
Is there a better way?
You need to supply your middleware function with a next callback:
function addApiKey(req, res, next) {
req.query.key = process.env.APIKEY;
next();
});
app.get('/api/:endpoint', addApiKey, function(req, res) {
// do your stuff here
});
I need an equivalent of following express.js code in simple node.js that I can use in middleware. I need to place some checks depending on the url and want to do it in a custom middleware.
app.get "/api/users/:username", (req,res) ->
req.params.username
I have the following code so far,
app.use (req,res,next)->
if url.parse(req.url,true).pathname is '/api/users/:username' #this wont be true as in the link there will be a actual username not ":username"
#my custom check that I want to apply
A trick would be to use this:
app.all '/api/users/:username', (req, res, next) ->
// your custom code here
next();
// followed by any other routes with the same patterns
app.get '/api/users/:username', (req,res) ->
...
If you only want to match GET requests, use app.get instead of app.all.
Or, if you only want to use the middleware on certain specific routes, you can use this (in JS this time):
var mySpecialMiddleware = function(req, res, next) {
// your check
next();
};
app.get('/api/users/:username', mySpecialMiddleware, function(req, res) {
...
});
EDIT another solution:
var mySpecialRoute = new express.Route('', '/api/users/:username');
app.use(function(req, res, next) {
if (mySpecialRoute.match(req.path)) {
// request matches your special route pattern
}
next();
});
But I don't see how this beats using app.all() as 'middleware'.
You can use node-js url-pattern module.
Make pattern:
var pattern = new UrlPattern('/stack/post(/:postId)');
Match pattern against url path:
pattern.match('/stack/post/22'); //{postId:'22'}
pattern.match('/stack/post/abc'); //{postId:'abc'}
pattern.match('/stack/post'); //{}
pattern.match('/stack/stack'); //null
For more information, see: https://www.npmjs.com/package/url-pattern
Just use the request and response objects as you would in a route handler for middleware, except call next() if you actually want the request to continue in the middleware stack.
app.use(function(req, res, next) {
if (req.path === '/path') {
// pass the request to routes
return next();
}
// you can redirect the request
res.redirect('/other/page');
// or change the route handler
req.url = '/new/path';
req.originalUrl // this stays the same even if URL is changed
});
I'm working on a basic blog in Express.js. Say I have route structure like this:
/blog/page/:page
I would also like a /blog route that is essentially an alias for /blog/page/1. How can I handle this easily in Express?
All routes are defined like such:
app.get('/path', function(req, res) {
//logic
});
Use res.redirect to tell the browser to redirect to /blog/page/1:
app.get('/blog', function(req, res) {
res.redirect('/blog/page/1');
});
app.get('/blog/page/:page', function(req, res) {
//logic
});
Use a shared route handler and default to page 1 if the page param is not passed:
function blogPageHandler(req, res) {
var page = req.params.page || 1;
//logic
}
// Define separate routes
app.get('/blog/page/:page', blogPageHandler);
app.get('/', blogPage);
// or combined, by passing an array
app.get(['/', '/blog/page/:page'], blogPageHandler);
// or using optional regex matching (this is not recommended)
app.get('/:_(blog/)?:_(page/)?:page([0-9]+)?', blogPageHandler);