I used to be able to do this to create an exported HTML page containing some data. But the code is not working with the latest version of Google Chrome (It works all right with Chrome 5.0.307.11 beta and all other major browsers).
function createExport(text) {
var target = window.open();
target.title = 'Memonaut - Exported View';
target.document.open();
target.document.write(text);
target.document.close();
}
Chrome now complains that the domains don't match and disallows the JavaScript calls as unsafe. How can I access and modify the document of a newly opened browser-tab in such a scenario?
I also got this problem when using a local page using the file:// protocol (in Chromium 5.0.342.9 (Developer Build 43360) under Linux). The exact error message is:
Unsafe JavaScript attempt to access
frame with URL about:blank from frame
with URL
file:///home/foo/bar/index.htm.
Domains, protocols and ports must
match.
Apparently the protocols don't match, but the good news is: when this page on a web server, Chromium also opens a new window as "about:blank", but it doesn't complain any longer. It also works when using a local web server accessed via http://localhost.
EDIT: there is bug filed upstream about this. According to this comment, it is fixed and it will be rolled into trunk shortly.
UPDATE: this bug is now fixed, the following test case works properly:
var target = window.open();
target.title = 'Memonaut - Exported View';
target.document.open();
target.document.write("test");
target.document.close();
Here is the explanation I think
http://groups.google.com/group/chromium-dev/browse_thread/thread/9844b1823037d297?pli=1
Are you accessing any data from other domain? Not sure, but that might be causing this problem.
One alternative would be a data: protocol URL.
https://developer.mozilla.org/en/data_URIs
http://msdn.microsoft.com/en-us/library/cc848897%28VS.85%29.aspx
var durl = "data:text/html," + encodeURIComponent(text);
var target = window.open(durl);
Supported in all modern browsers except IE7 and below.
you can also try closing self tab/window by using this code,
originally I've made this small greasemonkey script sometime ago in order to close
bad popups and ad windows, it worked fair (not too brilliant though)...
//window.addEventListener("load", function () {
window.addEventListener("onbeforeunload", function () {
try {
// clear inner html content to prevent malicious JS overrides.
document.getElementsByTagName("html")[0].innerHTML = "";
window.open("javascript:window.close();", "_self", "");
window.open("javascript:window.close();", "_self", "");
}
catch (e) {}
}(), false);
Related
I am developing a Mozilla Firefox extension using the Add-on SDK. On every tab change event, I want to read cookies of specified host which is open in another tab. I reached up to tab change, but am trying to figure out the way to get the cookies of specified host in recent activated tab.
var tabs = require("sdk/tabs");
tabs.on('activate', function(tab) {
// want to get cookies here.
});
Well, from within a tabs.on('activate') event handler, you have the tab. The tab object has a property url from which you can obtain the host. Once you have the host, you can get the cookies for that host. You have not stated what you want to do with them. So, here is just a way to enumerate them.
In order to use some methods of Services.cookies (nsICookieManager2) you will also need to require Chrome Authority.
var domainToUse = 'google.com';
var { Services } = require("resource://gre/modules/Services.jsm");
var { Cc, Cu, Ci} = require("chrome");
let cookieEnumerator = Services.cookies.getCookiesFromHost(domainToUse);
while (cookieEnumerator.hasMoreElements()) {
let cookie = cookieEnumerator.getNext().QueryInterface(Ci.nsICookie2);
console.log(cookie.host + ";" + cookie.name + "=" + cookie.value + "\n");
}
Update for newer versions of Firefox:
Note: At least by Firefox 50.0a2 (currently Firefox Developer Edition), it is necessary to use a slightly different call to getCookiesFromHost() to obtain the cookieEnumerator. Without the change, the call to getCookiesFromHost() will display a warning message in the Browser Console directing you to visit the nsICookieManager2 MDN documentation page which has no updated information on the warning, or any documentation on the change. I had to look in the source code to determine what was required. What appears to be desired is to pass in the current content document. However, from a background script that did not appear reasonable. The other way it is used is to just pass in an empty Object, {}. Thus, that line is changed to:
let cookieEnumerator = Services.cookies.getCookiesFromHost(domainToUse,{});
It is supposed to be for passing in "the originAttributes of cookies that would be be retrieved."
The above code is slightly modified from my answer to "How to set custom cookies using Firefox Add-on SDK (using Services from Firefox Add-on SDK)".
The app I am working on, currently uses XML dataisland files to retrieve the dropdown data. Below is the code that defines the file.
<xml id="DefaultDataIslands" src="../XMLData/DataIslands-<%=((User.Identity).Database)%>.xml">
</xml>
Below is an example code that uses these XML dataislands.
var oDataIsland = document.getElementById("DefaultDataIslands");
var oXmlNodes = oDataIsland.XMLDocument.selectNodes("XMLDataIslands/DataIsland[#ID='DIMRGroup']/Option");
This oDataIsland line is used about 4k times total in the application. The application itself is intranet, so, I can even ask the users to download the xml files directly. Whole point is to keep the changes required to minimum, while removing all traces of XML tags. I want to make sure that application works on Chrome once this thing is completed.
I checked the link from mozilla regarding the dataislands here. https://developer.mozilla.org/en/docs/Using_XML_Data_Islands_in_Mozilla
Below is the code based on that mozilla link.
var doc = document.getElementById(strDataSource).contentDocument;
var mainNode = doc.getElementsByTagName("DataIsland");
var oXmlNodes;
var strOptions = "";
//finds the selected node based on the id, and gets the options for that id
for (i = 0; i < mainNode.length; i++) {
if (mainNode[i].getAttributeNode("ID").nodeValue == strDataMember) {
oXmlNodes = mainNode[i].getElementsByTagName("Option");
}
}
This code reads the data properly, works perfectly in IE (10 with standards mode, no quirks), was easy enough change to do in the full solution.
Only problem is, document.getElementById(strDataSource).contentDocument; line fails in Chrome. This is the same line as what was mentioned in Mozilla's documentation. But somehow contentDocument property is undefined on chrome.
So, I need some other suggestion on how to get this fixed. I tried other methods, using HTTPRequest (too many request per page), using JSON (requires changing existing methods completely), using backend to process XML instead of doing it client side (requires architectural changes). Till now, all these ideas failed.
Is there any other method that I can use? Or should I fix the contentDocument issue?
To allow contentDocument in Chrome, you will have to use --allow-file-access-from-files. Following are the steps for doing so:
Get the url of your Chrome Installation path to your chrome
installation e.g
C:\Users-your-user-name\AppData\Local\Google\Chrome\Application>
Launch the Google Chrome browser from the command line window with
the additional argument ‘–allow-file-access-from-files’. E.g ‘path
to your chrome installation\chrome.exe
--allow-file-access-from-files’
Temporary method you can use each time you are testing
Copy the existing chrome launcher
Do as above and save it with a new name e.g chrome - testing
Alternatively, you can simply create a new launcher with the above and use it to start chrome.
Source
In the past this used to work:
// writing
var newTab = window.open();
newTab.document.write("<html><head><title>I'm just a tab</title></head>");
newTab.document.write("<body id='hello'>With some text on it</body>");
newTab.document.write("</html>");
newTab.document.close();
// reading what was wrote
newTab.document.getElementById('hello').addEventListener("click", custom_search_function(), false);
However now when I try to execute this code, Firefox mentions a security error:
Error: SecurityError: The operation is insecure.
I searched the forum for an alternative and this works:
var textOnPage = "<html><head><title>I'm just a tab</title></head><body>";
var newTab = window.open("data:text/html;charset=UTF-8," + encodeURIComponent(textOnPage));
newTab.document.close();
But I can't access the page via getElementById
newTab.document.getElementById('hello').addEventListener("click", custom_search_function(), false);
returns:
Error: TypeError: newTab.document.getElementById(...) is null
How can I write to this new tab and then go back to read it through functions such as getElementById?
You're falling foul of the Single Origin Policy. When you open a new window without a URL, by definition it can't have the same domain name as the original (opener) window.
You could instead have the window.open() call open another URL on your site (mostly blank html) and as part of its body.onload event handler (or jQuery.ready()) you could set up an event handler for the message event like this:
$(document).ready(function(){
window.addEventListener("message", receiveMessage, false);
});
function receiveMessage(evt)
{
if (evt.origin !== "https://your-domain.here")
return;
// do something with evt.data
$(document.body).append(""+evt.data);
}
In your originating window you call:
otherWindow.postMessage(message, "https://your-domain.here");
The postMessage API is now well supported across a variety of modern browsers.
You'll still not be able to directly reach in to maniuplate the content of otherWindow, but you can post messages back from otherWindow to your originating window to achieve the same effect. (e.g: put your content manipulation code in otherWindow's content and 'call' it from your originating window).
This used to work in a variety of browsers for a long time (in my past life as a web developer I actually took advantage of this technique for web applications). It used to be that window.open pages were treated mostly like they were from the same domain as the parent page (although the behavior was always a little weird and the url in the url bar was usually about:blank).
Now the standard is to open the pages with the url origin being about:blank, and while I can understand why it made sense to simplify things and I can understand the reason this breaks the previous behavior, but the issue here is that about:blank is not a real url so the standard cross-origin rules should be different, at least in the case of window.open calls.
Is there a real security threat here from allowing windows to write to pages they have opened? I do not think so, but it is possible. In the end, I am no longer a web developer and do not care that much about these things, but I would not be surprised if other people's applications broke as well.
I am getting the strange error "SCRIPT70: Permission denied jquery.js, line 21 character 67" on IE-9. Searched on google but could not find anything except a bug on CKEditor.
Position it showed just contains following:
P=navigator.userAgent,xa=false,Q=[],M,ca=Object.prototype.toString,da=Object.prototype.hasOwnProperty,ea=Array.prototype.push,R=Array.prototype.slice,V=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(typeof a==="string")if((d=Oa.exec(a))&&(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Sa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];
anyone run into this error?
*Additional Info:*We open an iframe and call some javascript functions inside this iframe.
thanks.
The SCRIPT70 error in IE9 occurs most likely when your iframe is calling some javascript (especially if it affects the parent page - e.g. hash change of parent url)
Check that your iframe's host/protocol/port number matches.
IE9 is exceptionally strict about the host name(down to the www portion in my case) and document.domain did not seem to provide a workaround for that.
Encountered this issue and fixed it while dealing with multiple iframes, hope this helps others with the same issue.
function Sizzle( selector, context, results, seed ) {
var match, elem, m, nodeType,
// QSA vars
i, groups, old, nid, newContext, newSelector;
// MY EDIT - this try/catch seems to fix IE 'permission denied' errors as described here:
// http://bugs.jquery.com/ticket/14535
try{
document === document; //may cause permission denied
}
catch(err){
document = window.document; //resets document, and no more permission denied errors.
}
if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
setDocument( context );
}
//...... snip .........//
}
http://jsfiddle.net/xqb4s/
I was having this exact problem with IE9 and in fact, it happens with IE11 as well.
My problem was I was opening a website via http (i.e. http://mywebsite.com) and an iframe within my code was trying to access a portion of the website using https. This was causing the error. Once I accessed the website using https, the error went away. A old bookmark was the cause of it using http and the site had been updated with https so check your URLS.
You cannot access any of your iframe's contents if it points to a different domain than the parent site.
If you are dealing with select element in your script maybe your problem is like mine
SCRIPT70: Permission denied when adding options to select element from a recently closed iframe
Recently I encountered this error. In the application I am working, I'm using TinyMce text editor for our email composer. This creates an iframe which contains the objects I need for an email composer. After seeing many blogs about the said error, I tried to programmatically remove the TinyMce text editor object then triggered the redirection. And it WORKED!
Facing a similar issue (maybe not with jquery.js but the same error description) the solution was a bit different from above. Actually I have searched for other iexplore.exe lines in regedit. I have found other two and changed it to 1 and it worked then.
hkey_local_machine\software\microsoft\internet explorer\main\featurecontrol\feature_protocol_lockdown
hkey_local_machine\software\microsoft\internet explorer\main\featurecontrol\feature_internet_shell_folders
If you run a 64-bit OS, make sure the value of this key is also set to 1: HKEY_LOCAL_MACHINE\SOFTWARE\**Wow6432Node**\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_OBJECT_CACHING\\iexplore.exe
Without this key we had random SCRIPT70: Permission denied errors in Internet Explorer 11.
Tip from this one page should help: http://forum.jquery.com/topic/strange-behaviour-in-ie9
Make sure that HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_OBJECT_CACHING\iexplore.exe is not set to 0 (it should be 1 or missing)
I have a set of HTML files using JavaScript to generate navigation tools, indexing, TOC, etc. These files are only meant to be opened locally (e.g., file://) and not served on a web server. Since Firefox 3.x, we run into the following error when clicking a nav button that would generate a new frame for the TOC:
Error: Permission denied for <file://> to get property Location.href from <file://>.
I understand that this is due to security measures within FF 3.x that were not in 2.x, in that the document.domain does not match, so it's assuming this is cross-site scripting and is denying access.
Is there a way to get around this issue? Perhaps just a switch to turn off/on within Firefox? A bit of JavaScript code to get around it?
In firefox:
In address bar, type about:config,
then type network.automatic-ntlm-auth.trusted-uris in search bar
Enter comma separated list of
servers (i.e.,
intranet,home,company)
Another way is editing the users.js.
In users.js, write:
user_pref("capability.policy.policynames", "localfilelinks");
user_pref("capability.policy.localfilelinks.sites", "http://site1.com http://site2.com");
user_pref("capability.policy.localfilelinks.checkloaduri.enabled", "allAccess");
But if you want to stop all verification, just Write the following line into users.js file:
user_pref("capability.policy.default.checkloaduri.enabled", "allAccess");
You may use this in firefox to read the file.
function readFile(arq) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var file = Components.classes["#mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
file.initWithPath(arq);
// open an input stream from file
var istream = Components.classes["#mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
istream.init(file, 0x01, 0444, 0);
istream.QueryInterface(Components.interfaces.nsILineInputStream);
var line = {}, lines = [], hasmore;
do {
hasmore = istream.readLine(line);
lines.push(line.value);
} while(hasmore);
istream.close();
return lines;
}
Cleiton's method will work for yourself, or for any users who you expect will go through this manual process (not likely unless this is a tool for you and your coworkers or something).
I'd hope that this type of thing would not be possible, because if it is, that means that any site out there could start opening up documents on my machine and reading their contents.
You can have all files that you want to access in subfolders relative to the page that is doing the request.
You can also use JSONP to load files from anywhere.
Add "file://" to network.automatic-ntlm-auth.trusted-uris in about:config