Offline-Friendly Forms
mxb.at
mxb.at
Be careful not to completely rely on navigator.onLine for this as your next request could be the first to fail, so you need to deal with submission errors and timeouts too (or safer: always put the data in local storage and remove once you have confirmation of a successful save).
The article seems good overall though, I can forgive leaving out some of the nitty-gritty like this to keep the main points clear.
A rough way to do this would be to add a hidden UUID value in the form data that is generated once up front and used by both the client and the server to ensure that the result of the first successful request can be cached and re-returned.
You really don't. You can, as mentioned above, have a hidden UUID field in the form that's used serverside to deduplicate submissions within a given timeframe.
(Or more likely and more on-topic, for the offline-friendly form if the application gets the error first, the application could be smart enough to try again...)
The UUID doesn't guarantee anything other than capability to prevent duplicate records from duplicate submissions. Something else has to be responsible to make sure the submission is not abandoned without user input, unless a 200 or other successful status is received.
Take a look at how Stripe guarantees at-most-once execution: https://stripe.com/blog/idempotency.
https://developer.mozilla.org/en-US/docs/Web/API/NavigatorOn...
If you need to support more browsers it isn't difficult. Just make a request to a small static asset or a health route and keep track of the online status yourself. You could even combine this with `navigator.onLine` for the best of both worlds.
https://stackoverflow.com/questions/7859972/storing-credenti...
Not storing that kind of stuff will need prompts to re-enter it too.
http://i.imgur.com/zauv4sK.png
Your disk could be encrypted, but not everyone's will be. It's better to just localStorage as it was intended.
Plus if you introduce a bug later down the line, you might not prune older localStorage entries, meaning they will stay there for much longer than you want. AND the user may not revisit your site ever again after going offline, which doesn't give you an opportunity to prune it.
local storage can be read using JavaScript from the same domain if you control all the JS on the domain, then this shouldn't be a problem. But if any other code is executed (i.e. via injection), they will be able to access the local storage
Nobody here is saying that an attacker can easily access your domain's localstorage, but just expressing the sentiment that "storing plaintext passwords is bad in almost any case".
Just like you can store plaintext passwords in your application database, and theoretically they are safe, but if a bad guy gets in your users are screwed, not just on your site but on others.
What are the pros and cons between these 2 approaches?
$.ajax({
type: "POST",
url: url,
data: $("#form").serialize(), // serializes the form's elements.
success: function(data)
{
//do stuff
}
});
Instead of serializing the form, jquery can also just serialize a flat js object. I wouldn't call that complicated enough to make a distinction. (it's probably really easy in modern plain js too)Starting to get complicated now, might be easier to just do $("#form").submit().
Sure, it's more complicated than $("#form").submit(). But it's close enough that other considerations become more important (e.g. do I want a page reload, do I have to populate the form first etc)
Every time I see this double function safety pattern a small part of my JS heart dies.
> window.addEventListener('online', this.checkStorage);
window.addEventListener('online', this.checkStorage.bind(this)); class Foo {
checkStorage = () => {
// Do check storage stuff here
}
}
And the language will take care of binding the function. (Really, it's just doing `this.checkStorage = this.checkStorage.bind(this)` in the constructor).