I was wondering how you would use node.js to parse a string parameter from a request url akin to express.
I know this is possible with express, but I would like to know how it can be done with node.js without express.
Express example:
var app = require('express')();
app.get('sample/request/url/:id', function(req, res) {
var parameter = req.params.id;
});
If your are using connect (or just http module) you can use RegExp:
With http:
var http = require('http');
http.createServer(function (req, res) { // Note there's no next here
var match = req.url.match(/^sample\/request\/url\/(.+)$/);
var id = match ? match[1] : null;
}).listen(3000);
...
With connect:
var connect = require('connect');
connect.createServer(funcion(req, res, next) {
var match = req.url.match(/^sample\/request\/url\/(.+)$/);
var id = match ? match[1] : null;
}).listen(3000);
...
This is the simple case. If you want to have your own routing middleware you should start with an array of RegExps (that can be generated dinamically from a String that you add) and loop through them until you find a match.
Each route element should have its RegExp and also its parameters, so that once you find a match you can extract and append the parameters to the req object with an appropriate name that you choose.
EDIT:
As robertklep pointed out in his comment, you can check paramify. Its code is very clear and does some of the things I said in the last part of the answer. For example, you can see it has a function regify to dinamically contruct the RegExps and a loop to extract the parameters of a match:
var params = []
for (var i = 1; i < matches.length; i++) {
var key = reg.keys[i - 1]
if (key) {
params[key.name] = matches[i]
} else {
params.push(matches[i])
}
}
You can get the url property from req and parse as you want:
var server = require('http').createServer(function (req, res) {
console.log(req.url);
// would log "/sample/request/url/123"
});
The parse part can be done using RegEx.
Related
I'm building a REST api server in Node js. Let's say I have an Api - http://localhost:3000/api/employee/:employeeId. And I want to fetch the employeeId parameter without using any framework such as Express js. If possible what would be a better approach ?
**If you Need the Employee Id from Url So You can use this - **
const express = require('express');
const router = express.Router();
router.get('http://localhost:3000/api/employee/:employeeId',getUserById);
getUserById(req, res) {
console.log('---EmployeeId ----',req.params.employeeId);
}
Here's a vanilla js function to get the url segments
function UrlSegments() {
// Change this to the correct url if its not
// the url that you want to process
// You can also do window.location.pathname to process
// the current path.
let urlSegments: string[] = /api/employee/:employeeId
// Remove the empty string before the first '/'
if (urlSegments.shift() === "")
urlSegments.slice(1, -1);
// Remove the empty string after the last '/'
if (urlSegments.slice(-1)[0] === "")
urlSegments.splice(-1, 1);
return urlSegments;
}
string employeeId = UrlSegments()[2];
I am trying to properly read cookies on my node server that were set by me through the browser console on localhost:3000 like this:
document.cookie = "tagname = test;secure";
document.cookie = "hello=1"
In my node server, I use sockets.io, and when I get a connection request, I can access a property which goes like this:
socket.request.headers.cookie
It's a string, and I always see it like this:
'io=QhsIVwS0zIGd-OliAAAA' //what comes after io= is random.
I've tried to translate it with various modules but they can't seem to parse the string. this is my latest attempt:
var cookie = require('cookie');
io.sockets.on('connection', function(socket) {
socket.on('addUser', function(){
var a = socket.request.headers.cookie;
var b = cookie.parse(a); //does not translate
console.log(b);
});
}
I obviously want to get an object with all the cookies that were sent by each io.connect on the browser.
I've been trying to solve it for 5 hours and I really don't know what I am doing wrong here.
Use the Cookie module. It is exactly what you are looking for.
var cookie = require('cookie');
cookie.parse(str, options)
Parse an HTTP Cookie header string and returning an object of all cookie name-value pairs. The str argument is the string representing a Cookie header value and options is an optional object containing additional parsing options.
var cookies = cookie.parse('foo=bar; equation=E%3Dmc%5E2');
// { foo: 'bar', equation: 'E=mc^2' }
Hope this helps
Without Regexp
//Get property directly without parsing
function getCookie(cookie, name){
cookie = ";"+cookie;
cookie = cookie.split("; ").join(";");
cookie = cookie.split(" =").join("=");
cookie = cookie.split(";"+name+"=");
if(cookie.length<2){
return null;
}
else{
return decodeURIComponent(cookie[1].split(";")[0]);
}
}
//getCookie('foo=bar; equation=E%3Dmc%5E2', 'equation');
//Return : "E=mc^2"
Or if you want to parse the cookie to object
//Convert cookie string to object
function parseCookie(cookie){
cookie = cookie.split("; ").join(";");
cookie = cookie.split(" =").join("=");
cookie = cookie.split(";");
var object = {};
for(var i=0; i<cookie.length; i++){
cookie[i] = cookie[i].split('=');
object[cookie[i][0]] = decodeURIComponent(cookie[i][1]);
}
return object;
}
//parseCookie('tagname = test;secure');
//Return : {tagname: " test", secure: "undefined"}
Try using socket.handshake instead of socket.request
The IO cookie is the default cookie socket.io uses as a user id. You can set this but if you don't it will create one and set a hash value to it.
Read about the option here.
I don't think it is a code issue. Here is an example of your code. When I added the cookie test and set it to 1
var app = require('express')();
var http = require('http').Server(app);
var cookie = require('cookie')
var io = require('socket.io')(http);
var port = process.env.PORT || 3000;
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.sockets.on('connection', function(socket) {
socket.on('chat message', function(){
var a = socket.request.headers.cookie;
var b = cookie.parse(a); //does not translate
console.log(b);
});
});
http.listen(port, function(){
console.log('listening on *:' + port);
});
Server Output
{ io: 'TxvLfvIupubZpOaGAAAF', test: '1' }
If I changed the it to this.
var io = require('socket.io')(http, {
cookie : 'id'
});
The output would change this to.
{ id: 'ZJPSwFsQAje0SrgsAAAD', test: '1' }
Node.js + Express project. Working on pagination I want to create the pagination links. Imagine the following URL:
http://server.com/products?page=1&color=red&size=big
I am here:
exports.products = function(req, res) {
}
I could use req.query.page and req.url and compose new URL for next and previous pages using regex and string functions for increasing/decreasing page parameter, but the question is:
Is there a cleaner method?
Some bodyparser feature?
Simple example (without input validation, but that's left as an exercise):
var toQS = require('querystring').stringify;
exports.products = function(req, res) {
...
req.query.page = Number(req.query.page) + 1;
var newUrl = req.path + '?' + toQS(req.query);
...
};
I am creating a get request in node js. I want the base url path as http://localhost:80/sample and different requests as /v1, /v2.
So, the concatenated url will be http://localhost:80/sample/v1?querystring=10.
How can I segeregate the base path as http://localhost:80/sample, since when I try to get the pathname, I am getting /sample/v1?
Please help me with node js not using express.
UPDATE:
function onRequest(request, response) {
var pathName = url.parse(request.url).pathname;
}
where the request.url is localhost:80/sample/v1?q=10.
I need to validate if its either "v1" or "v2" by fethcing in the url instead of validating with the entire pathname like pathname.indexOf('v1') process something.
So, I don't know why do you prefer scheme /{method}/{api_version}, because companies are prefer reversed to your order. (E.g. twitter console).
Example #1, if your method doesn't contain additional slashes:
function onRequest(request, response) {
var pathName = url.parse(request.url).pathname.split('/');
var version = pathName[2]; // v1 or v2
var methodName = pathName[1]; // sample
}
Example #2, if you method will contain additional /, e.g. /user/19292/v1:
function onRequest(request, response) {
var pathName = url.parse(request.url).pathname;
var match = pathName.match(/\/v\d+$/);
if(match != null) {
var version = match[0]; //v1 or v2
var methodName = pathName.replace(/\/v\d+$/, ''); // /user/19229
} else {
// No version was provided
}
}
I'm using express 3.0 and when I'm trying to resolve some queries I want to test if there's other component on the db that match these id's. Any way, this is the code I'm not getting to work:
function(req, res) {
var Parking = mongoose.model('Parking');
var parkingId = req.params.id;
var userId = req.user['_id'];
Parking
.findOne({'_id': parkingId}, function(err, parking) {
var parkingUserId = parking.userId;
if (userId == parkingUserId) {
...
} else {
...
}
req.params.id is inside url and req.user['_id'] comes from a middleware.
Although I'm calling this url with the same id on both fields.... it keeps getting false...
Why I'm doing wrong? thanks!
You need to convert parkingUserId from a bson ObjectId object to a string:
if (userId.toString() == parkingUserId.toString())