ajax and local/session storage pattern - javascript

I'm building a web app that uses ajax to communicate with the server. Basically, the user requests a record, it comes back in json, it's added to the DOM and the user makes changes to it. When the user requests the next record, the current record is stringified and sent back to the server and the following record comes back.
All this works really well.... as long as the user keeps requesting records. However, I am wondering how to handle the situation where the user stops his work: how do I get the last record updated?
I thought of adding the working record to the local storage while he's editing it and at each edit, updating the local storage and if he logs on next time and there's still a record in there, ajax it when he logs on. The problem with his approach is that if another user logs on to the same computer, then when that new user logs on, he's updating the data of another user.
I thought of using the window.unload event also; but that doesn't solve the problem of the user closing his browser before the final update.
What are some good ways to handle this issue. Thanks for your suggestions.

I would consider a 'draft-like' feature. Where you could upload changes after a certain amount of time of no input, for instance, after 15 seconds of no input, push those changes.

If your app requires login, you could key the localStorage using their ids like so:
localStorage.getItem( "user13434" )
would retrieve data for user13434
localStorage.getItem( "user12345" )
would retrieve data for user12345
If the information is sensitive but not too sensitive you could add encryption, but it can be decrypted by experienced users which is why it must not be too sensitive.

Related

Updating LocalStorage with the same data in the same time on multiple tabs causing problems

first of all i'm a beginer front end developer and i'm not a native english speaker so sorry for any mistake i made in my first question :D I'm working on project in Vue that was started by someone else. It uses websocket to display some notifications from server and i spotted a bug associated with this. The notifications are stored in object that pulls data from localStorage using VueUse's useStorage:
const state = reactive({
liveNotifications: useStorage("liveNotifications", []),
notificationsCount: 0,
});
And when data is received from ws it's being added to the beginning of the array like this:
connections.alerts.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data?.status) {
return;
}
state.liveNotifications.unshift(data);
state.notificationsCount += 1;
};
The problem is, when more than 2 tabs are opened and ws send some notifications, the localstorage starts acting weird like its trying to add the same objects over and over and notificationsCount is jumping (for example) from 2 to 3 and vice versa.
Is there any way to e.g. prevent app from updating localstorage multiple times if the data given from ws is the same on all tabs. Or maybe there's another way to make this work properly?
I've tried some solutions from web but to be honest i'm not really sure why is this happening and i didn't know what exactly i was supposed to look for so if someone has better knowledge than me and can help me understand i'm here to learn :)
The problem is: both tabs will read/write to the same "file".
The localStorage read-only property of the window interface allows you to access a Storage object for the Document's origin; the stored data is saved across browser sessions.
MDN - Window.localStorage
Suggestion here is to use sessionStorage instead:
[...] the difference is that while data in localStorage doesn't expire, data in sessionStorage is cleared when the page session ends.
Whenever a document is loaded in a particular tab in the browser, a unique page session gets created and assigned to that particular tab. That page session is valid only for that particular tab.
It sounds like you need a shared worker.
Since you are receiving the same data it is reduntant to keep two connections.
You should handle your websocket connection in a shared worker, then upon receiving the data save it to the localStorage, then post a message to the tabs to update the UI.

Dump state into json or tsv (backend)

Many of the tutorials for survey / forms in React tend to cover front-end mechanics only. In my case, I pretty much have the front-end where I want it but have come to realize I know virtually nothing about back-end programming.
I thought it best to take baby steps, so maybe adding a line to a json/tsv after the user clicks a button would be a reasonable goal. I'm imagining the user manipulates all the bells and whistles I have then once he/she clicks "submit" then a new row is added to a "master_data.tsv" file on the back end.
Just for illustration, the portion of the state I would like to save is:
state = {
selectBoxes: [
{id:1, strategies:['Strat1','Strat2', 'Strat3','Strat4','Strat5']},
]
For context, this state gets passed down to drop-down menu components that have event listeners to record the user's choice. I have it so that the state is updated to reflect the user's desired choice. But I have not figured out how to dump the data on the back end once the choice is selected and the user click's "submit."
Question
Assuming click-flow:
Toggle dropdown menu -> choose item -> click "submit" button
How would I add a new row to master_data.tsv after each "submit" event?
(can ignore unique user qualification and all the fancy stuff, maybe we can settle for each new row has an id though. )
I would recommend taking a step back and first, thinking about the actual flow and data persistence of your application.
I would recommend creating a backend server (any language) that offers you to post the data to it via an API endpoint (usually a REST API with a POST endpoint)
After you receive your data, you have to persist it. Either in a database, in a session or on disk.
The last step is to retrieve the data in the desired format (tsv).
Either create another endpoint to return the data, or return the entire file already on POST.
Here is an example flow of how it could look like
Front-End: Send data on submitting to the backend (POST /entries)
Backend: Receive data and store it (disk, database …)
Front-End: Receive data from backend (GET /entries)
Backend: Returns entries as tsv
This way you are rather flexible and decoupled. Later on, you could exchange the format easily to JSON, XML, CSV …
Your source of truth should always be your storage layer (database, file on disk)

how to pop up a Notice Span when user just log in (but not just refresh to the home page)?

I do not know how to detect it is the first time that user login the web.
I thought i should write a pop-up span on the jsp that user firstly saw when he login.but the issue is then he refresh the page,the notic will show again,that is ridiculous.
I need detect if it is first login means to detect if the user JUST LOGIN or NOT REFRESH the page
how and where shall I detect if it is the first time user login ? and then i can make mind if the notice span pop up.
and I think it should use cookies or session,but which one should i use?
Maintain a field in database table that check if it is first login than show a popup and after that change the value of that field so that Popup do not appear next time.
Ex:
if($data['first_login'] == 1)
{
// show popup
}
If you want to show it only to the new user (the time user registers) you can use a table column in database where you can use it to check if the user if logging in for the first time (e.g firtsLogin the column name = 1 ). If he is logging in for the first time you show the pop-up and change the value of the field to 0.
Otherwise if you want to show to users that are logged in to a specific device for the first time you should use cookies.
I suppose that you want to detect the user logging in to your web-site the first time. There are multiple ways that you can do it depending on your desire to spend additional time writing the code, the location of your logging-in logic (client or server side), security that you want to have while proving your users with login functionality. In all cases - you would have to store the data whether the user has logged in for the first time. I think you are seeking a fast solution that will work without a big care for privacy or security as working with client-side cookies isn't the safest way to store data. The alternatives to cookies are web tokens, url query string, server-side sessions and data-base (RDBMS) storage.
Storing and retrieving the data on the client-side using COOKIES. They are the pieces stored in the user's web browser. Cookies were created to help servers remember the data about the user next time he enters the web-site. The most common usages are: to store location (if accepted by user), web-site locale (language in which the user was browsing the site), products added to cart, etc. Following that approach you can create cookie after the user has logged in to your web-site as follows:
This should be run by your JavaScript.
document.cookie = "firstLogin=true";
After having done that, you would have to add JavaScript logic that will hook-up to user's/client's COOKIE data and read up whether he has logged in the first time before.
This would probably look like a simple JavaScript cookie look-up.
var cookieData = document.cookie;
This will return all of your user's cookies that has been previously stored when he visited your web-site. It will return it as a string concatenated with "; ". If we had previously stored only one cookie, we would get firstLogin=true;
In case if you have multiple cookies set before, you would have to parse the cookie string and extract the data either imperatively by plain procedural JavaScript code or by writing the function which will be able to do that repeatedly. Detailed examples of writing such functions could be found here.

Access to different databases, prevent user errors PHP

I'm developing a tool that allows user to change database connection.
So user has a select box where he selects the desire database. I have a total of 4 different databases, but structure is the same in all, only data change.
If user works only with 1 open tab, I don't have any kind of problem. But if user works with few tabs , a lot of security problems can happen.
For example:
Tab 1 - User wants edit a row from database 1
In the same time, user change Tab2 to database 3.
So when he is going to save tab 1, probably it would save to database 3, as it was the last change.
I'm saving the selected database on $_SESSION var.
My code right now, I have a form where user selects the database. And on _init.php I have a simple switch case that require a different config.php depending of selected database.
Some ideas how i can prevent errors like this happen?
If you store the active connection in $_SESSION, there can be only one active connection regardless the number of tabs you open in your browser as the session is shared across tabs.
Instead, you can give a counter or a numeric identifier for each connection:
Example:
1 = connection 1
2 = connection 2
...
If the user changes the connection from your select box, use a redirect a send a GET parameter with the connection number.
Example:
if I choose connection 1 the browser redirects to index.php?cn=1
If in another tab I use connection 2, the browser redirects me to index.php?cn=2
You will need always to send your connection id by GET or POST, and receive it instead of looking it in your $_SESSION var.
Hope it helps
If each concurrent tab is permitted to use a separate database connection, then each concurrent tab will need to specify that information when posting requests to the server.
This could be as simple as including the identifier for the database in a hidden field in each form. When the user selects a different database on that page, update that hidden field. (Mostly guessing on the "hidden field" structure here, since we don't know how your forms are laid out. But the point is that the form should contain this value.)
This becomes an overall more RESTful approach, moving away from session state and toward a state transfer driven by the page itself. Which in general is a good thing.
Basically, since the request for the action being performed (saving a record) needs to know where to save it, include that piece of information in the request itself rather than trying to juggle that information server-side.
Quite honestly I would take a different approach to your issue.
Set up sub-domains on your server which point to the same exact web folder and have hard-coded DB connection settings.
db1.example.com
db2.example.com
db3.example.com
db4.example.com
Now the user will have to log into the correct sub-domain in order to perform operations on the desired DB so session_start() will actually create a unique session per sub-domain.
The user will be able to have 4 tabs open without the fear of using the wrong DB.
So your db_config.php file can look like this:
switch($sub_domain)
{
case 'db1.example.com':
// Code for connecting to DB1
break;
case 'db2.example.com':
// Code for connecting to DB2
break;
case 'db3.example.com':
// Code for connecting to DB3
break;
case 'db4.example.com':
// Code for connecting to DB4
break;
}
As for the idea with creating a <select> box for choosing your DB, you can just implement some JS to open a new tab pointing to the correct sub-domain.

Using AJAX and jQuery to store data

I am looking for a way to use AJAX and jQuery to store data from one form in another without losing the values. I want to be able to keep this data away from the front end user and allow them to remove the information should they wish to. I need to be able to get this information out when the user submits the data. I would like to be able to store the values in an associative PHP array if possible, for example:
<?php
$information = array(
"first_information"=>array(
"name"=>"Sam Swift",
"age"=>21
),
"second_information"=>array(
"name"=>"Example Name",
"age"=>31
)
);
?>
I would have used a database for this but because of volume this will not be possible. I want to keep the data away from the user so that they have no access to it at all, the data should be held where the user has no way to see it, access it or change it. This is due to the nature of the data and all of it should be as secure as possible.
Any information that you store client-side is naturally going to be accessible and mutable by the client. If this sensitive data is data that the user is entering, then you really shouldn't worry about them manipulating the data (because that is what they are supposed to be doing). If however it is data that is being sent by the server - and never displayed or used in that form by the client - this is data that should never leave the server in the first place.
Ajax is not specifically a solution to this problem - whether you send the data asynchronously (i.e., piecemeal with Ajax) or as a full HTTP post is immaterial. You need to store the sensitive data on the server only along with a session ID to associate it with the client session.
Without knowing exactly what data you are storing nor what you are doing with it, it is difficult to advise you how to proceed. You should rethink how you are structuring your application if you are sending sensitive data for the client to work with. The client should only ever see the input and the results. The processing should be done on the server.
For example: perhaps your user is adding an amount to a bank balance. The user enters the amount on the client. but you don't want the client to see or be able to modify the actual value. You could send the balance to the client, perform the addition operation, then send the total back to the server. Far better would be for the client to send the amount to add to the server, which would then add the value to the balance, and return a confirmation for the client to display.

Categories

Resources