SessionStorage and LocalStorage allows to save key/value pairs in a web browser. The value must be a string, and save js objects is not trivial.
var user = {'name':'John'};
sessionStorage.setItem('user', user);
var obj = sessionStorage.user; // obj='[object O开发者_StackOverflow中文版bject]' Not an object
Nowadays, you can avoid this limitation by serializing objects to JSON, and then deserializing them to recover the objects. But the Storage API always pass through the setItem
and getItem
methods.
sessionStorage.setItem('user', JSON.stringify(user));
var obj = JSON.parse(sessionStorage.getItem('user')); // An object :D
Can I avoid this limitation?
I just want to execute something like this:
sessionStorage.user.name; // 'John'
sessionStorage.user.name = 'Mary';
sessionStorage.user.name // 'Mary'
I have tried the defineGetter
and defineSetter
methods to intercept the calls but its a tedious job, because I have to define all properties and my target is not to know the future properties.
The solution is to stringify the object before calling setItem on the sessionStorage.
var user = {'name':'John'};
sessionStorage.setItem('user', JSON.stringify(user));
var obj = JSON.parse(sessionStorage.user);
Could you not 'stringify' your object...then use sessionStorage.setItem()
to store that string representation of your object...then when you need it sessionStorage.getItem()
and then use $.parseJSON()
to get it back out?
Working example http://jsfiddle.net/pKXMa/
Either you can use the accessors provided by the Web Storage API or you could write a wrapper/adapter. From your stated issue with defineGetter/defineSetter is sounds like writing a wrapper/adapter is too much work for you.
I honestly don't know what to tell you. Maybe you could reevaluate your opinion of what is a "ridiculous limitation". The Web Storage API is just what it's supposed to be, a key/value store.
This is a dynamic solution which works with all value types including objects :
class Session extends Map {
set(id, value) {
if (typeof value === 'object') value = JSON.stringify(value);
sessionStorage.setItem(id, value);
}
get(id) {
const value = sessionStorage.getItem(id);
try {
return JSON.parse(value);
} catch (e) {
return value;
}
}
}
Then :
const session = new Session();
session.set('name', {first: 'Ahmed', last : 'Toumi'});
session.get('name');
Use case:
sesssionStorage.setObj(1,{date:Date.now(),action:'save firstObject'});
sesssionStorage.setObj(2,{date:Date.now(),action:'save 2nd object'});
//Query first object
sesssionStorage.getObj(1)
//Retrieve date created of 2nd object
new Date(sesssionStorage.getObj(1).date)
API
Storage.prototype.setObj = function(key, obj) {
return this.setItem(key, JSON.stringify(obj))
};
Storage.prototype.getObj = function(key) {
return JSON.parse(this.getItem(key))
};
var user = {'name':'John'};
sessionStorage['user'] = JSON.stringify(user);
console.log(sessionStorage['user']);
Session storage cannot support an arbitrary object because it may contain function literals (read closures) which cannot be reconstructed after a page reload.
You can create 2 wrapper methods for saving and retrieving object from session storage.
function saveSession(obj) {
sessionStorage.setItem("myObj", JSON.stringify(obj));
return true;
}
function getSession() {
var obj = {};
if (typeof sessionStorage.myObj !== "undefined") {
obj = JSON.parse(sessionStorage.myObj);
}
return obj;
}
Use it like this:- Get object, modify some data, and save back.
var obj = getSession();
obj.newProperty = "Prod"
saveSession(obj);
You could also use the store library which performs it for you with crossbrowser ability.
example :
// Store current user
store.set('user', { name:'Marcus' })
// Get current user
store.get('user')
// Remove current user
store.remove('user')
// Clear all keys
store.clearAll()
// Loop over all stored values
store.each(function(value, key) {
console.log(key, '==', value)
})
CustomHook is one of the best ways to store a token as an object by using sessionStorage in React 17.0.1.
Follow these instructions:
Implement sessionStorage get/set inside a custom function:
export default function useToken() { const getToken = () => { const tokenString = sessionStorage.getItem('token'); const userToken = JSON.parse(tokenString); return userToken?.token; }; const [token, setToken] = useState(getToken()); const saveToken = (userToken) => { sessionStorage.setItem('token', JSON.stringify(userToken)); setToken(userToken.token); }; return { setToken: saveToken, token, }; }
This function can be imported and used as a hook in other components like:
import useToken from './useToken'; const { token, setToken} = useToken(); // call CustomHook const handleSubmit = async (event) => { event.preventDefault(); // call functionAPI const token = await loginUser({ username, password, }); setToken(token); // AUTOMATICALLY token will be stored to sessionStorage of browser };
精彩评论