I'm using the id variable across different functions. The id is defined outside of the functions. Could this cause the variable to overwritten when receiving multiple simultaneous requests? Is the behavior the same when this is done in the browser instead of in Node.js?
var id;
server.get('/myapp', function (req, res, next) {
id = uuid.v4();
}
Yes, it causes conflicts
If your request handlers have any asynchronous operations in them which allow more than one request to be in flight at the same time, then YES, the use of a module level variable that more than one request may access will cause conflicts and one request could trounce the variable that another was using.
In a nutshell, don't do this
Module level variables are only for data that ALL requests can safely access and share. Data for a single request should be inside the request handler or a property on the request or response object or some similar-type object that is per-request and not shared among multiple requests.
Data needed only during the processing of a request
So, if you just need access to some data for the duration of this particular request, then you can put it in a local variable inside the request handler and you can pass it to any other functions you may call that need it while processing that request. Or, you can assign it as a property on the req object which is unique for each separate request and then pass the req object to any other functions you are calling that need access to the data.
Data needed from one request to the next, but different for each user
If you are trying to keep track of some data from one request to the next for one particular client, then you can't store it this way at all. You will likely need to use a session manager so you can create a lasting session that can be correlated with one particular browser from one request to the next. express-session is a popular session manager that makes it pretty easy.
The way a session manager works is that the first time a given browser hits your server, it is assigned a unique cookie. That cookie contains an encrypted session ID. Then, the session manager creates a session object that is indexed by that session ID. When a second request from the same browser comes in, then express-session gets that previously set cookie, decrypts the sessionID, looks up the corresponding session object and lets you then access any data you may have stored in the session object on behalf of this particular user.
Related
I have an express server, and it handles all kind of functionalities that I want to log. I dont want to log only incoming requests, I want to log for example how much time it took for a certain function that handles data to execute. I also have a client that passes username as a header to each request in the server, and I want the username to be a part of every log. I can't store the username in a class or a global variable, as it won't be correct when multiple requests from different users are made. My logger is a class that you can simply call in order to log, for example: logger.log("blah", payload)
I don't want to pass the userId to every function where I want to log, what can I do?
Things I thought to do:
pass userId to every function, though I don't want to do it
Maybe somehow make the req known to the logger? But I don't know how to do it correctly
in an express.Js app ;i want to write a controller class that handles the request & response for other controllers for example add data to locals in res object or delete data from req.session etc.
is there a way i can do it without passing req or res as an argument
can i access them globally
The correct and possible way is to pass the req object as an argument to functions that need to use it.
Placing it in global variables will not work because multiple requests can be processed at the same time if for example requests use some asynchronous calls as part of their processing. So, multiple requests will stomp on other requests and will make it really hard to track down bug.
node.js is a server that can potentially handle many requests for many clients. Server may have many requests all in flight at the same time and thus plain globals you wish to use cannot be used for request-specific data.
I'm using node.js and I need to pass an array of objects with res.redirect(),
I tried with querystring but it's not a good idea because the array with too big and I could get Error 414 Request URI too long.
using connect-flash isn't a good way either, it's more useful for passing messages.
And I don't want to use req.app.locals for that.
Hope you can help me with any idea.
Assuming the client here is a browser that you want to just automatically follow the redirect and then inherit some new state when the server generates the page for that newly redirected URL, then here are some options:
If you already have a session established for the user, then you can store the data in the session, then include a single query parameter that tells the route handler for the page you're redirecting to to look in the session to get the relevant data.
You could also create a temporary server-side cache of data. Generate a random key (likely a timestamp plus a random number). Store the data in a server-side Map using that key. Then put the key into a query string on the redirect. Then, in the route handler for the new, redirected page, it will see the query string parameter and it can grab that key out of the query string and access the data from the server-side Map serving as a temporary cache (and probably remove it from the cache too). This scheme works in a session-less environment.
You then need some scheme for cleaning up unused data from the cache so it doesn't accumulate. Probably what makes sense it to timestamp the data and then have a setInterval() timer that just removes things from the Map if their timestamp is older than xx minutes.
If the request is an Ajax call rather than a regular browser page request, then you don't need to use a redirect at all. You can just return the content that they would have gotten if they then followed your redirect. Then, you don't have to invent a temporary place to store the data. You can just use the data to generate the desired page and return it.
Store the data as session data and serve it back up to them when they land on the landing page.
Another way would be to have the client request the data asynchronously once the redirect has been performed.
On page load, say for a particular route for (e.g. https://localhost:8000/home/index), a service is called and the response from the service is rendered to the page at the client side.
On the same page, I have a link that pops up a Backbone.js modal and from the modal a click event triggers which hits another url (e.g. https://localhost:8000/home/index2) upon which another service call triggers and the response is rendered to another html page.
On the same html page, I want to display a value which I got from the first service call on page load. However, I am unable to retain that value as there are two different requests each time. Hence, I cannot even append the value from first response to the request object and use it a second time.
You can use JavaScripts Web Storage API to storage information on client browser.
MDN Web Storage API
For example, If you are on the first screen and call a service, store the service information on localStorage
localStorage.setItem('firstService', serviceResponseObject);
Once you are navigated to second page, you can use localStorage to read to previous service information
localStorage.getItem('firstService');
There are multiple ways to store state between requests.
From the server, if you're using say Express etc, you could store the result in a Session. Or you can even store state in the requests query params, or from a POST request.
You could also store some data on the client end, using say Cookies or localstorage.
What you choose really depends, it might be best if you explain in more detail what sort of information your passing between pages.
If it's just a simple value, I would go for using query params.
eg. Just place in your url https://localhost:8000/home/index2?value=123, and then from node.js, req.query.value would have your value.
When a client logs in, i want to store inside a dictionary the ids of the clients / sessions as keys inside a dictionary mapped to some data (In case there is no need for a dictionary and meteor has a way to map a single variable with client specific data it would be even better).
I am not familiar with developing Meteor packages and Javascript at all, so my question is: Where do i put this dictionary so i can access it from everywhere on the server and where can i get the clients ids?
Wished behaviour:
1. Client logs in -> Server registers new client id
2. Client calls function on server
3. Inside the function the server gets the right data according to the clients id for further processing
Inside a package (https://github.com/steffow/meteor-accounts-saml) i set up a global variable but when i tried to access it from javascript, inside the imports/api directory, the global variable was undefined.
You could use the Presences package to store information about each logged in user, https://github.com/dburles/meteor-presence. It automatically creates unique ids for these.
These database records are available both in the client and server. You can either fork and extend this package to store more information, or create another database table to store your information.