I have got a bug with some javascript code that it's hard to reproduce (so no jsfiddle, sorry). Exactly the same browser (FF 37.0.2), but two different machines, and I can only reproduce the bug on one of them.
I suspect the issue has something to do with localStorage and the fact that I check if an item is there outside $(document).ready().
Is that required? Do I need to wait for the DOM to be ready before reliably accessing localStorage? Is my hypothesis plausible?
localStorage is not something that needs to be "loaded" asynchronously. It is available the moment the page starts to load and can be used by Javascript anywhere in the page. If the browser has to fetch values form somewhere (e.g. the disk), that is done synchronously when you request the data or before.
There is no need to wait with $(document).ready() before accessing localStorage. The cause of your issue must be something else.
FYI, you can read the spec on WebStorage here: http://dev.w3.org/html5/webstorage/#dom-localstorage. There is no indication in the localStorage section of that document that JS code must "wait" before accessing.
Related
So this is more of a curiosity, rather than a problem I'm facing. I've come across a website that calls window.location.reload() before the load event fires. How would you break out of this refresh loop, as a user? Can it even be done?
Anyways, I've tried the following:
Replacing window.location.reload (via greasemonkey)
This is not possible since window.location is read-only.
Listening for window.onbeforeunload and hitting cancel (via greasemonkey)
The reload call happens before the document loads. This means the beforeunload event is never fired due to lack of transient activation, so there's no prompting for you to cancel the reload.
Block JavaScript (or: block all network requests)
This does disable the reload. And also the entire site, so it's not ideal.
Block the request to the specific file with the reload call (via devtools)
Same as above, since the file in question is a Webpack bundle, containing the majority of the site's functionality.
Inject a userscript that replaces the function calling windows.location.reload() with an equivalent function that doesn't call windows.location.reload() (via greasemonkey)
I don't think it's possible for this site. Webpack loads every function in an IIFE, so it's not obvious how to modify the function in question before it gets passed as a callback and becomes untouchable. In any case, this approach doesn't generalize.
Place a breakpoint at the window.location.reload call, and modify some local function to throw an error before it can call reload (via devtools)
This didn't work (on Firefox, at least) -- try it out, (function() {throw new Error(), window.location.reload()})(). Due to the comma operator, it'll reload despite the thrown error, and every Webpack expression seems to be a string of comma-separated statements so there's no avoiding this. This approach also doesn't generalize.
Manually modify the construction of the global Webpack window.webpackChunk_N_E table (via greasemonkey)
I don't know about modern Webpack to know if this could be done, but I tried replacing the particular method in question in that table with a ()=>{}. It didn't work -- I believe the method was already passed as a callback before the tire change. We are dealing with a function that is far too powerful to care about its replaced reference in some mere global table.
Close the tab
I gave up.
Did I miss anything obvious, or is it impossible by design to break this particular kind of refresh loop in the browser (short of disabling JavaScript)?
I have a long javascript function (about 72k minified) that is required on several pages of my site. My existing method to employ the function on my pages is to call the script by the usual means:
<script type="text/javascript" src="./javascript/complex_function.js"></script>
However, this involves reading and parsing the script on each page on which it is required. If I could store the function in my browser's memory and simply call it from there, then it would seem more efficient and faster (yes?)
Sadly, it seems that sessionStorage only supports the storages of keys and values that are strings. I've tried stringifying the function (as discussed elsewhere re: Javascript objects being stored in sessionStorage or localStorage), like so:
// First call the function in an initial page of the site:
<script type="text/javascript" src="./javascript/complex_function.js"></script>
// Then stringify it and store in sessionStorage:
sessionStorage.setItem('my_function', JSON.stringify(my_function));
Thereafter, in theory, I should be able to retrieve the function from sessionStorage anywhere session is active on my site, like this:
var temp = JSON.parse(sessionStorage.getItem('my_function');
...although (1) this doesn't work, or at least I can't find a way to make it work, and (2) even if I could make it work, it would still involve parsing the function, which would defeat the purpose (right?)
So...what is the best way to store a Javascript function in memory (no cookies, please) so that it can be called from any page on my site? (Or is this possible at all?)
Your browser will already do this for you. It will cache scripts upon their first download to reduce loading times, so once it's loaded the first time successive requests for that file will be quicker as it is pulled from the local machine, not the server.
first of all, I don't think it's a good idea to store js functions in memory.
And per my experiences, the sessionStorage only store string values, so you can try eval()
I have this code in my javascript file. I had run the checkMarx tool on my project and it is showing me this
Client_DOM_Stored_Code_Injection security issue
on the window.sessionStorage.getItem('anyItem') code. Anyone has any clue how to resolve this issue.
Thanks in advance.
A better (modern) solution to prevent code injections and XSS is CSP (Content Security Policy).
I did not tested it with local/sessionStorage, but it worths a try.
More info here: http://content-security-policy.com/
The only downside is its browser support (no IE support).
I guess it's because any value can be stored in the localStorage, meaning an "evil" stringified code could be stored and thus executed (with eval for example) when retrieved. Read this, it might helps you, there is an example on XSS in localStorage.
Other helpful link : How secure is localstorage?
If you app store something in the localStorage with myKey as key for example, any other site can override it by storing the same key. So if you rely on reading a value from a key you defined, you can't be 100% sure it will contain a value you (meaning your code) stored.
False, see MDN Thanks to #Nils
To prevent (or try at least) this kind of attack, you should create a function where every value set in/retrieved from the localStorage are first evaluated to check if it contains code that could be harmful.
Also, use use_strict in your code, it can be useful to prevent such things, but it still can be passed by.
Edit
Based on the #SilverlightFox idea, I've reached this and found it interesting.
I have an app with a top frame and two framesets inside this top frame. While navigating to other pages the top frame remains the same and only the framesets change. I use localStorage for storing some data (which is also stored on the server, but if it is on client we don’t make the round trip each time), this feature is not available on IE7 so we decided to try to simulate localStorage in IE7.
The idea was to store a variable localStorage on the top frame (only if localStorage was not available). Whenever localStorage was not available on the top frame we would then create a dummy localStorage object with _data,getItem(),setItem(),removeItem(). The life of this object would last as long as the life of the top frame, which would save us a lot of round trips to the server and therefore offer a great performance boost in IE7.
The problem that I’m having is that whenever I change the frame (not the top frame) and I get the localStorage from the top frame and try to get an item using the window.top.localStorage.getItem(‘…’); I get the error message can't execute code from a freed script.
Any ideas why I get this??
I would recommend you to take a look in jStorage which provide common interface for localStorage, or old globalStorage or userData behavior. Probably you can use jStorage directly (see here) and save your time writing the corresponding code or you can use the same idea for your own implementation. More information about old userData behavior you can find for example here.
Maybe I will be repeating what Brilliand already shared, but as I don't understand his answer entirely I will share some ideas/advice as well:
First of all make sure that all relevant frames are hosted on the same domain (including things like opening the top frameset on www.domain.com and having internal links without the "www.")
In case you need cross domain scripting check out the internet for some relevant tricks to achieve that (the theory).
It might be worth trying to wrap all access to the localStorage within a few functions in the top frame (I can think of a few reasons which could theoretically cause problems with direct access to objects in the top frame... although this should as far as I know work).
Try reinitialize all references to subframes, you might for example have forgotten adding a "var" in front of a window.frames reference and not reinitalizing it after navigation (it would explain the error message, although it seems quite an unlikely mistake).
It might be also worth making sure to not keep any references to top.localStorage itself inside any of the child frames (although, again, it shouldn't cause any problems).
You might want to consider using a cross platform localstorage wrapper. They tend to work with proprietary functions in IE allowing a localStorage like functionality in IE as well (1MB max, but that should be enough). An example of such a library is store.js
See What causes the error "Can't execute code from a freed script"
That error message occurs when code created by the child frame (which has since been closed) is accessed. This means, at least, that you can't keep JavaScript functions around after the window they came from was closed; I'm not certain that applies to data objects as well, but it might. If so, then simple storage of JavaScript objects in the top window won't work.
It should be possible to work around this problem by ensuring that you completely detach the data from the child window before storing it. This can be done by having the storage function (which must be created by the parent window alone) JSON encode that data, and store the encoded string. Retrieval would be less finicky, since the retrieved object doesn't need to be kept around longer than the child window that retrieved it.
I'm having a problem with a Java JSF application: In a certain case, a user action causes an Ajax HTTP request that updates the UI correctly, but then immediately a second request is triggered, causing a second, incorrect update.
How can I find out (preferably using Firebug) where exactly that second request is triggered? There's a lot of minified framework JS code, so I don't know where to place breakpoints. Setting the form onsubmit handler to console.trace did not help, I suppose because these are independant Ajax requests.
While trying out the suggestions in the answers, I found that Firebug already has exactly what I need out of the box: the Console tab displays all requests, and for Ajax requests it shows the file and line number where they originate, which tells me where to set my breakpoint...
Using Firebug you can set Breakpoints on DOM (HTML) Mutation Events if you have some HTML changes in your UI update.
If the framework abstracts the AJAX requests, you should be able to trace the calls to the abstractions. For example, jQuery allows this through its global AJAX event handlers.
Another, more robust way to tackle the problem would be to replace the XHR object and trace calls made to it (i.e. if the framework does not provide the above abstraction or if the calls that you want to use don't use the abstraction). Just replace the GM_log with console.trace in the script at the end of the page and include it in the page you're testing.
What I personally have done in these case is using an HTTP proxy that can put a request or response 'on hold'. E.g. Burp Proxy (this is actually a security tool, but it works great for debugging purposes)
Start up the proxy and configure your browser to use it. Navigate to the page where the roque requests originates from and activate intercepting requests (this might take some practice as Burp Proxy can be a rather complicated tool).
Now do the user action, if all goes well the proxy intercepts it and waits for your confirmation to let it go through. Do this. Then you'll probably see the second request coming and being intercepted by the proxy as well. Don't let this one through, but instead switch to Firebug and suspend into the debugger. Hopefully you'll then be able to see where it originates from. Edit: on second thoughts, the asynchronous nature of AJAX probably means you won't be able to see what the exact spot is via this method anyway... :(
At least you can also configure it to intercept responses. Both requests and responses can be edited on the fly, which can be great for experimenting and debugging and might help in narrowing down the problem.
Might this would help, caller is a method in Function object of javascript.
console.log(arguments.callee.caller.toString());