I have a web app, which has 2 html pages(html1,html2 related to javascript file js1.js,js2.js)
When I click a button on html1, it will navigate to html2.
I know there is the way transfer the parameter using url from html1/js1/js to html2/js2.js.
Is there a mechanism that set up variables both j1.js j2.js can access?(likes global variable in c)
Welcome any comment?
This is not directly possible as each page loads with its own window object namespace.
i.e. A global variable in js1.js (used in page1.html) is actually a member of the window object in page1. Similarly a global variable in page2.html is a member of that page's window object. The 2 window objects are totally different in the sense there is no site wide window or site object that can store global variable for use throughout a site
You can however use window.localStorage to share variables/values across pages in your site.
Example:
Setting value:
window.localStorage.setItem('myglobal', "hello");
Getting value:
var myglobal = window.localStorage.getItem('myglobal');
A hackish solution is to store it into the window.name field. This is shared in the same window/tab of the browser.
I personally don't like it. That variable isn't meant to be used this way.
There are libraries to persist state: http://pablotron.org/?cid=1557
Or, you could write your own code to store the variable in session (requires server-side programming), in HTML5 storage, in cookies, etc.
Variables and values can be passed through pages via querystring.
Have a look at this SO article.
If you strictly need to create a Javascript global variable, then you have to include a common snippet in both pages:
var myGlobalVar;
But this only represent a storage accessible by both scripts. You have to set its value anyway.
You can either parse window.location.href to extract the parameters, set cookies in one page and retrieve them in the other (example here) which also requires parsing or use a server-side solution.
Most probably if you look for in interwebs you can find parsers for URLs and Cookies.
Related
In a Google spreadsheet using the Script Editor, I do function calls, but I am not quite sure if the best way to store persistant data (data that I will continue to use) is to use global variables (using objects, arrays, strings), or there is a better way to store data.
I don't want to use cells which could be another way.
Another question, is it possible to create (pseudo) classes in this environment? Best way?
Both ScriptProperties and ScriptDB are deprecated.
Instead, you should be using the new class PropertiesService which is split into three sections of narrowing scope:
Document - Gets a property store that all users can access within the current document, if the script is published as an add-on.
Script - Gets a property store that all users can access, but only within this script.
User - Gets a property store that only the current user can access, and only within this script.
Here's an example persisting a user property across calls:
var properties = PropertiesService.getScriptProperties();
function saveValue(lastDate) {
properties.setProperty('lastCalled', lastDate);
}
function getValue() {
return properties.getProperty('lastCalled');
}
The script execution environment is stateless, so you cannot access local variables from previous runs, but you can store getScriptProperties() in a local variable because it will be re-run for each return trip to the server so it can be called in either method.
If you need to store something on a more temporary basis, you can use the CacheService API
Persistent data can be stored using the Class ScriptProperties:
http://code.google.com/googleapps/appsscript/class_scriptproperties.html
All values are stored as a string and will have to be converted back with the likes or parsInt or parseFloat when they are retrieved.
JSON objects can also be stored in this manner.
My experience has been that every query to retrieve or store values takes a long time. At the very least, I would cache the information in your javascript code as much as possible when it is safe. My scripts always execute all at once, so I don't need to keep global variables as I simply pass the retrieved data arrays around, manipulate them, and finally store them back in one fell swoop. If I needed persistence across script invocations and I didn't care about dropping intermediate values on close of the webpage, then I'd use globals. Clearly you have to think about what happens if your script is stopped in the middle and you haven't yet stored the values back to Google.
A have a react application using a single page. I call index.html and use ajax(axio) and update the page. I do not use any routing.
I have some global variables and will use in the whole scope of the application. The variables are primitive type integer for example. Some of the variables may be updated during the app lifecycle and some remain constant. But I should be able to reach them from all react components/javascripts. They may contain business related constants or example decimal format mask, keeping them private in each component will not be useful.
There is no need/reason to store it on the disk (localStorage).
Question is: what is the best way (performance etc) storing the global variable foo in the app?
window.foo = 10 or
window.sessionStorage.foo = 10
AFAIK, window.foo is for a single page and sessionStorage allows using within multiple pages within the same origin. What is best in my case when I use a single page? Are there any other drawbacks of window.foo usage? Security is not important, the vales stored are not sensitive. Most critical is the performance.
You probably want to use context rather than either of those. From that documentation:
Context is designed to share data that can be considered “global” for a tree of React components, such as the current authenticated user, theme, or preferred language.
Definitely don't use global variables. The global namespace is incredibly crowded, and adding to it is generally not best practice. If you did use a global for this, I'd recommend using just one, and having it refer to an object with properties for the various pieces of information you want to share. Note that they'll be window-specific.
One reason to possibly consider using sessionStorage (or perhaps periodically synchronizing your React context to it) is if you want changes in one window to be reflected in another window. Two windows/tabs from the same origin share the same sessionStorage and can get an event (storage) when the other one changes that storage. So if the global information were an app theme (say, light vs. dark), changing it in one tab could also affect the other tab if you respond to the storage event by updating your React context. Note that sessionStorage (and localStorage) only store strings, so the usual thing is to convert to JSON when storing (JSON.stringify) and from JSON when loading (JSON.parse).
In my extension, I need to access some data stored by page JavaScript.
However, I also need to make sure the page cannot trick my extension into running arbitrary code. The data I need should be stored in plain old value properties (if I understand what they are) on a JS object bound to the page's window, but just in case, I want to be sure not to call any malicious code if it's present.
Is there a way to safely access this data from a content script, treating the JS object (and its children) as a simple dictionary?
I've found two pages that might offer some help:
This page describes a method of getting a reference to the page's window object, but it is unsafe to do so.
This page appears to show that Xray vision provides safe access to the value properties of an object, but does not seem to explain how to get Xray vision for a page-script object, at least from a content-script rather than actual chrome code.
Is there some way to combine these two to allow safe access to the data?
I'm wondering which would be better practice. Polluting the global namespace with global variables for intra-session persistence or using localStorage instead?
So in other words set a global variable on launch, change its value in a function when required and reference it in a third function, or use localStorage.setItem then localStorage.removeItem when the value is no longer needed?
Will doing either one increase memory efficiency?
LocalStorage is primarily for persistent data across sessions.
In your case, as your looking for an intra-session persistence, global variables have clear advantages.
I will start with cons of global variables first.
It uses the global namespace, any third party js code can manipulate it
A page refresh can wipe off your data
Well, that's it. If we consider the cons of LocalStorage, the list will raise your eyebrows.
set and get are slow and can be a performance bottleneck for large datasets
only strings are allowed; you may have to serialize your data before setting
I would surely vote up for LocalStorage if your use case involved inter-session storage. However, in your scenario, the only benefit you see is the removeItem function for which you have the delete counterpart for global variables.
This article may be helpful: http://www.sitepoint.com/html5-browser-storage-past-present-future/
As now consider to using DI in frameworks like Angular.
In Mozilla's JavaScript environment, it is possible to load other script from a URL using the loadSubScript() method of the mozIJSSubScriptLoader interface.
It is possible to specify an object used as the scope object for the script being executed. However, as explained in this Stackoverflow answer, "undeclared variables will still be created in the outer scope and the outer scope will be searched for variables that cannot be resolved in the subscript scope."
This answer recommends to use Components.utils.Sandbox as an alternative.
However, this mechanism apparently enables security restrictions. For Mozilla bug 876089, I tried out simply replacing the regular JS object with a sandbox. The loaded script could then no longer use Components.utils, placed in the scope object as "Cu":
EXCEPTION: Permission denied for to call method UnnamedClass.import
Now the question: In the Mozilla environment, how can I best load scripts in a way that just prevents leaking of symbols via the caller's global object, but still allows it to use all the symbols explicitly placed in the scope object without imposing any security restrictions?
Indeed, using a Sandbox is the right approach. Security settings can be managed by using a special principal as the scope object, instead of a plain JavaScript object.
By using the system principal, all security checks are disabled.
The code then looks like this:
Components.utils.import("resource://gre/modules/Services.jsm");
var systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
var scopeObject = new Components.utils.Sandbox(systemPrincipal);
// set properties of the scope object like this:
// scopeObject.someProperty = someValue;
var loader = Components.classes["#mozilla.org/moz/jssubscript-loader;1"]
.getService(Components.interfaces.mozIJSSubScriptLoader);
// Set uri to the uri of the script to load
loader.loadSubScript(uri, module, "UTF-8");