localstorage undefined on ie11 (windows 10) what is the solution? [duplicate] - ie11-developer-tools

The localStorage object in Internet Explorer 11 (Windows 7 build) contains string representations of certain functions instead of native calls as you would expect.
This only breaks with vanilla JavaScript and sites like JSFiddle have no problem with this code but I suspect it's because there are localStorage polyfills in place that correct it.
Take this HTML page code for example:
<!DOCTYPE html>
<script>
localStorage.setItem('test', '12345');
alert(localStorage.getItem('test'));
localStorage.clear();
</script>
This works perfectly well in all my installed browsers except for IE11. An error occurs on the first line 'SCRIPT5002: Function expected'.
Taking a look at what type the setItem function actually is in the IE developer tools console, states that it's a string...?
typeof localStorage.setItem === 'string' // true
Printing out the string for setItem displays the following:
"function() {
var result;
callBeforeHooks(hookSite, this, arguments);
try {
result = func.apply(this, arguments);
} catch (e) {
callExceptHooks(hookSite, this, arguments, e);
throw e;
} finally {
callAfterHooks(hookSite, this, arguments, result);
}
return result;
}"
Oddly enough, not all functions have been replaced with strings, for example, the corresponding getItem function is indeed a function and works as expected.
typeof localStorage.getItem === 'function' // true
Changing the document mode (emulation) to 10 or 9 still doesn't resolve the problem and both result in the same error. Changing the document mode to 8 gives the following error 'Object doesn't support this property or method' which is expected since IE8 doesn't support localStorage.
Is anyone else having the same issue with IE11 on Windows 7 where the localStorage object seems 'broken/corrupt'?

Turns out this is a problem in the base version of IE11 (11.0.9600.16428) for Windows 7 SP1.
After installing a patch to update to 11.0.9600.16476 (update version 11.0.2 - KB2898785) the issue gets resolved. Links to other versions of Windows (32-bit etc.) can be found at the bottom of the patch download page.

It's not just IE11's fault.
Probably WEINRE is injected into the page. It hooks into several system functions to provide Developer Tools functionality, but IE11 interprets assignments to the localStorage and sessionStorage properties wrong, and converts the hook functions into strings, as if they were the data that is going to be stored.
There's a comment in the apache/cordova-weinre repo which says:
#In IE we should not override standard storage functions because IE does it incorrectly - all values that set as
# storage properties (e.g. localStorage.setItem = function()[...]) are cast to String.
# That leads to "Function expected" exception when any of overridden function is called.
object[property] = hookedFunction unless navigator.userAgent.match(/MSIE/i) and (object is localStorage or object is sessionStorage)
Looks like it's either an old version of WEINRE being used, or this change hasn't been officially released (it's been there since 2013).

My localStorage returned undefined and I couldn't figure out why - until I realized that it was because I was running the HTML-page (with the localStorage script) directly from my computer (file:///C:/Users/...). When I accessed the page from a server/localhost instead it localStorage was indeed defined and worked.

In addition to the already excellent answers here, I'd like to add another observation. In my case, the NTFS permissions on the Windows %LOCALAPPDATA% directory structure were somehow broken.
To diagnose this issue. I created a new Windows account (profile), which worked fine with the localStorage,so then I painstakingly traversed the respective %LOCALAPPDATA%\Microsoft\Internet Explorer trees looking for discrepancies.
I found this gem:
C:\Users\User\AppData\Local\Microsoft>icacls "Internet Explorer"
Internet Explorer Everyone:(F)
I have NO idea how the permissions were set wide open!
Worse, all of the subdirectories has all permissions off. No wonder the DOMStore was inaccessible!
The working permissions from the other account were:
NT AUTHORITY\SYSTEM:(OI)(CI)(F)
BUILTIN\Administrators:(OI)(CI)(F)
my-pc\test:(OI)(CI)(F)
Which matched the permissions of the parent directory.
So, in a fit of laziness, I fixed the problem by having all directories "Internet Explorer" and under inherit the permissions. The RIGHT thing to do would be to manually apply each permission and not rely on the inherit function. But one thing to check is the NTFS permissions of %LOCALAPPDATA%\Microsoft\Internet Explorer if you experience this issue. If DOMStore has broken permissions, all attempts to access localStorage will be met with Access Denied.

Related

How to navigate Edge extension local storage callback requirements

I'm trying to access the local storage data in Edge set by my options page, using my popup script. Is there a current, working example of this available?
I was using localStorage, but it would only update the popup if I reloaded the extension after saving changes in my options page. I want to make it easier on the user by allowing the popup to access it immediately after saving, without reloading. I found the browser.storage.local.get(), but documentation conflicts everywhere I look, and I can't find viable working examples.
I have used, per Edge documentation:
browser.storage.local.get("sample");
But it throws an error requiring a callback function. So then I used:
let sample = browser.storage.local.get("example");
sample.then(ifGood, ifBad);
I get an error regarding property "then".
Then I simply tried adding a callback to the action itself:
sample = browser.storage.local.get("example", callbackFunction);
function callbackFunction(data){
alert(data);
}
The end alert should display a string, but it just displays an empty Object. How do I access the data returned in the callback? I tried callbackFunction(this) as an argument in the get, but it throws an error about the syntax of the get.
I found a work-around using browser.runtime.reload() in the Options page when saving the changes. It still reloads the extension, but it does it without requiring the user to do it manually.
You should use this syntax:
browser.storage.local.get(propertyName | null, callbackFn)
where
callbackFn = function fn(resultObject) {...}
When you pass null you will get whole storage object.
Look for example 1 or example 2 in my Edge extension.

How to detect extension on a browser?

I'm trying to detect if an extension is installed on a user's browser.
I tried this:
var detect = function(base, if_installed, if_not_installed) {
var s = document.createElement('script');
s.onerror = if_not_installed;
s.onload = if_installed;
document.body.appendChild(s);
s.src = base + '/manifest.json';
}
detect('chrome-extension://' + addon_id_youre_after, function() {alert('boom!');});
If the browser has the extension installed I will get an error like:
Resources must be listed in the web_accessible_resources manifest key
in order to be loaded by pages outside the extension
GET chrome-extension://invalid net::ERR_FAILED
If not, I will get a different error.
GET chrome-extension://addon_id_youre_after/manifest.json net::ERR_FAILED
Here is an image of the errors I am getting:
I tried to catch the errors (fiddle)
try {
var s = document.createElement('script');
//s.onerror = window.setTimeout(function() {throw new Error()}, 0);
s.onload = function(){alert("installed")};
document.body.appendChild(s);
s.src = 'chrome-extension://gcbommkclmclpchllfjekcdonpmejbdp/manifest.json';
} catch (e) {
debugger;
alert(e);
}
window.onerror = function (errorMsg, url, lineNumber, column, errorObj) {
alert('Error: ' + errorMsg + ' Script: ' + url + ' Line: ' + lineNumber
+ ' Column: ' + column + ' StackTrace: ' + errorObj);
}
So far I am not able to catch the errors..
Any help will be appreciated
The first error is informative from Chrome, injected directly into the console and not catchable by you (as you noticed).
The GET errors are from the network stack. Chrome denies load in either case and simulates a network error - which you can catch with onerror handler on the element itself, but not in the window.onerror hander. Quote, emphasis mine:
When a resource (such as an <img> or <script>) fails to load, an error event using interface Event is fired at the element, that initiated the load, and the onerror() handler on the element is invoked. These error events do not bubble up to window, but (at least in Firefox) can be handled with a single capturing window.addEventListener.
Here's an example that will, at least, detect the network error. Note that, again, you can't catch them, as in prevent it from showing in the console. It was a source of an embarrasing problem when Google Cast extension (that was exposing a resource) was using it as a detection method.
s.onload = function(){alert("installed")};
s.error = function(){alert("I still don't know")};
Notice that you can't distinguish between the two. Internally, Chrome redirects one of the requests to chrome-extension://invalid, but such redirects are transparent to your code: be it loading a resource (like you do) or using XHR. Even the new Fetch API, that's supposed to give more control over redirects, can't help since it's not a HTTP redirect. All it gets is an uninformative network error.
As such, you can't detect whether the extension is not installed or installed, but does not expose the resource.
Please understand that this is intentional. The method you refer to used to work - you could fetch any resource known by name. But it was a method of fingerprint browsers - something that Google is explicitly calling "malicious" and wants to prevent.
As a result, web_accessible_resources model was introduced in Chrome 18 (all the way back in Aug 2012) to shield extensions from sniffing - requiring to explicitly declare resources that are exposed. Quote, emphasis mine:
Prior to manifest version 2 all resources within an extension could be accessed from any page on the web. This allowed a malicious website to fingerprint the extensions that a user has installed or exploit vulnerabilities (for example XSS bugs) within installed extensions. Limiting availability to only resources which are explicitly intended to be web accessible serves to both minimize the available attack surface and protect the privacy of users.
With Google actively fighting fingerprinting, only cooperating extensions can be reliably detected. There may be extension-specific hacks - such as specific DOM changes, request interceptions or exposed resources you can fetch - but there is no general method, and extension may change their "visible signature" at any time. I explained it in this question: Javascript check if user has a third party chrome extension installed, but I hope you can see the reason for this better.
To sum this up, if you indeed were to find a general method that exposed arbitrary extensions to fingerprinting, this would be considered malicious and a privacy bug in Chrome.
Have your Chrome extension look for a specific DIV or other element on your page, with a very specific ID.
For example:-
<div id="ExtensionCheck_JamesEggersAwesomeExtension"></div>

Developer documentation for previous releases of the Chromium\Google Chrome [duplicate]

I love what chrome offers me through its extension API.
But I always find myself lost in the jungle of what API is supported by which chrome version and when did the last chrome.experimental feature make it into the supported extensions.
The Chrome extension page gives me a nice overview what is supported, but without mentioning since what version. The same is true for the experimental API overview. Is that specific API still experimental or is it already supported in canary, for example.
If I try a sample from the chrome Samples website I usually have to change some API calls from chrome.experimental.foo to chrome.foo or find out that it is not supported at all. (What happened to chrome.experimental.alarm?) That usually means to just use the trial and error approach to eliminate all errors, until the sample works.
tldr;
So, I'm wondering is there an overview page which tells me since what version, what API is supported or when it was decided to drop an experimental API. And if there is no such page, what is the recommended way or your personal approach to deal with this situation?
On this page, the process of generating the official documentation (automatically from the Chrome repository) is described. On the same page, you can also read how to retrieve documentation for older branches. Note that the documentation is somehow incomplete: Deprecated APIs are included immediately, although they're still existent (such as onRequest).
What's New in Extensions is a brief list of API changes and updates (excluding most of the experimental APIs). It has to be manually edited, so it's not always up-to-date. For example, the current stable version is 20, but the page's last entry is 19.
If you really need a single page containing all API changes, the following approach can be used:
First, install all Chrome versions. This is not time consuming when done automatically: I've written a script which automates the installation of Chrome, which duplicates a previous profile: see this answer.
Testing for the existence of the feature:
Write a manifest file which includes all permissions (unrecognised permissions are always ignored).
Chrome 18+: Duplicate the extension with manifest version 1 and 2. Some APIs are disabled in manifest version 1 (example).
Testing whether a feature is implemented and behaving as expected is very time-consuming. For this reason, you'd better test for the existence of an API.
A reasonable manner to do this is to recursively loop through the properties of chrome, and log the results (displayed to user / posted to a server).
The process of testing. Use one of the following methods:
Use a single Chrome profile, and start testing at the lowest version.
Use a separate profile for each Chrome version, so that you can test multiple Chrome versions side-by-side.
Post-processing: Interpret the results.
Example code to get information:
/**
* Returns a JSON-serializable object which shows all defined methods
* #param root Root, eg. chrome
* #param results Object, the result will look like {tabs:{get:'function'}}
*/
function getInfo(root, results) {
if (root == null) return results;
var keys = Object.keys(root), i, key;
results = results || {};
for (i=0; i<keys.length; i++) {
key = keys[i];
switch (typeof root[key]) {
case "function":
results[key] = 'function';
break;
case "object":
if (subtree instanceof Array) break; // Exclude arrays
var subtree = results[key] = {};
getInfo(root[key], subtree); // Recursion
break;
default:
/* Do you really want to know about primitives?
* ( Such as chrome.windows.WINDOW_ID_NONE ) */
}
}
return results;
}
/* Example: Get data, so that it can be saved for later use */
var dataToPostForLaterComparision = JSON.stringify(getInfo(chrome, {}));
// ...

Copy/Paste Not Working in Chrome Extension

Following Copy/Paste code not working in Chrome Extension,
I need to write Chrome Extension that copy and paste data using clipboard.
I write following code in Backgroung.html page, but its not working.
function buttonClick(){
document.getElementById('initialText').select();
chrome.experimental.clipboard.executeCopy(1, function() {
alert("Copy");
document.getElementById('nameText').focus();
chrome.experimental.clipboard.executePaste(1, function() {
alert("Paste");
});
});
}
As of Chrome 13, clipboard access is no longer experimental.
The commands are now document.execCommand('paste'), document.execCommand('copy') and document.execCommand('cut').
However, permissions need to be added to your manifest: "clipboardRead" and "clipboardWrite".
Try implementing the above and see how you get on.
To eliminate the obvious; have you added the "experimental" permission to your manifest and are you using the latest dev build of Chrome as listed in the official documentation?
Otherwise, I'm not sure what may help you as I don't use the experimental API due to them not being usable in production. There is a workaround for copying without using the experimental API (using an input field and document.execCommand) but I'm not sure how to paste without it.
EDIT:
I've just noticed that experimental.clipboard is not longer listed on the experimental API page. It may be that this namespace has been deprecated/abandoned as can happen when using the experimental API. A simple test for this would be inserting;
console.log(typeof chrome.experimental.clipboard);
console.log(typeof chrome.experimental.clipboard.executeCopy);
console.log(typeof chrome.experimental.clipboard.executePaste);
Which should output the following the console for your background page;
> object
> function
> function

sharepoint: Using a Content Editor Web Part this error occurred:"Cannot retrieve properties at this time."

I have a content editor web part. Whenever I edit the content and then click save, the following errors occurred:
"Cannot retrieve properties at this time."
"Cannot save your changes"
How do you fix this?
I tried googling it.. there are some similar cases but not exactly the same. I tried this link:
www.experts-exchange.com/OS/Microsoft_Operating_Systems/Server/MS-SharePoint/Q_21975446.html
and this one:
support.microsoft.com/kb/830342
and this one:
blogs.msdn.com/gyorgyh/archive/2009/03/04/troubleshooting-web-part-property-load-errors.aspx
I found the answer!! apparently using mozilla firefox it worked. Then I found out that there is a javascript error in IE, this javascript error doesnt happened in firefox. how ironic!
Are you doing anything to modify the URL in an HTTPModule? I ran into this problem on a publishing site where a module was hiding the "/pages" part of the URL. Modifying the CEWP via the page when accessed w/o the "/Pages" wasn't working, but with the "/Pages" it was.
Example:
Got error: http://www.tempura.org/webpartpage.aspx
Worked: http://www.tempuri.org/pages/webpartpage.aspx
I don't see how this is an answer -- "don't use IE".
In my case (and apparently many others) it has something to do with ISA + SharePoint + host headers. I will post the fix if I find one.
I have had problems with this before and have found recycling the Application Pool often corrects the problem.
Rodney
IE8 -->
Tools --> Compatiblity View Settings --> CHECK THIS : Display All Websites in ....
If you are editing a webpart page, make sure that it is checked out. Sometimes the document library the webpart pages are in will have a "force check out to edit" option and it will give you errors if the webpage itself isn't checked out.
I had this same error recently. In javascript, I had written some prototype overrides (see examples below) to add some custom functions to the string and array objects. Both of these overrides interferred with SharePoint's native JavaScript somehow in IE. I removed the references from the master page and this issue was FIXED. Currently trying to find a work-around so I can keep them because things like the string.format function is very nice to have...
//Trim
if (typeof String.prototype.trim !== 'function') {
String.prototype.trim = function(){
return this.replace(/^\s+|\s+$/g, '');
}
}
//Format
String.format = function() {
var s = arguments[0];
for (var i = 0; i < arguments.length - 1; i++) {
var reg = new RegExp("\\{" + i + "\\}", "gm");
s = s.replace(reg, arguments[i + 1]);
}
return s;
}
I also faced the same problem. Finally it worked for me using url /Pages/Contact-Us.aspx instead of clean URL. It worked only with IE browser. Don't know why this was happening but anyhow it worked with me.
Use IE browser
Use Pages in the URLinstead of clean URL.
to me,
compatibility mode in IE8, to work

Resources