You'll need Opera 9.62 to see what this is all about... Because that is the only browser that behaves strange when I do cross-sub-domain JavaScript calls (with Ajax involved). Please consider the following three simple files and place them at appropriate domains.
foo.html (parent of boo.html iframe) at foo.example.com
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>foo</title>
<script type='text/javascript'>
document.domain = 'example.com';
function sendRequest() {
window.frames['boo'].sendRequest();
}
</script>
<head>
<body>
<input type="submit" value="sendRequest" onclick="sendRequest();" />
<iframe name="boo" src="http://boo.example.com/boo.html"></iframe>
</body>
</html>
boo.html (iframe of foo.html) at boo.example.com
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>boo</title>
<script type='text/javascript'>
document.domain = 'example.com';
function sendRequest() {
var request = null;
if (window.XMLHttpRequest) {
request = new XMLHttpRequest();
} else {
request = new ActiveXObject('Microsoft.XMLHTTP');
}
if (request) {
request.open('GET', 'http://boo.example.com/helloworld.php', true);
request.onreadystatechange = function() {
if (request.readyState == 4) {
var result = request.responseText;
alert(result);
}
}
request.send('');
}
}
</script>
<head>
<body>
</body>
</html>
helloworld.php at boo.example.com
<?php
echo 'Hello World!';
?>
If you test the above-stated code in browsers other than Opera (tested on v9.62), it works like a charm (I have tested in Safari, Firefox, Chrome). In Opera, it does not work and an error with security violation message is thrown. Does anybody know what the matter is?
I have found out a solution to the problem and I will post it here a bit later (I'd also like to see your solutions), but I'd like to learn more about the issue as well - can anybody explain it?
NB: I have set up all the files at my own server, so you can check it out here
UPDATE: I just tested it on the newest Opera 10.63 and it does not have such a problem. So you'll definitely need to use Opera v9.62 to observe the problem.
Some older Opera versions had a known bug that made setting document.domain affect the security context for XMLHttpRequest. Hence, after setting document.domain the script is no longer allowed to load contents from the server it actually came from.
The recommended solution is to simply upgrade to a version not affected by the bug, however if you absolutely need to support 9.6x you can easily detect the exception and fall back to using postMessage() for cross-domain communication. (In such an old version, you will need to call document.postMessage() - in newer versions it's window.postMessage() but it older versions of the HTML5 specification it was originally defined on document.)
Related
I'm new to Javascript and am learning the basics via a textbook that focuses on its applications in IE 7+ and Firefox 2+. However, I am using Chrome and am getting the following error when running the program given in the book: "blocked a frame of origin 'null' from accessing a cross-origin frame." Can anyone tell me what is causing the error and how I can fix it? The two programs are below.
//This is the program being loaded into the browser
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Example</title>
<script type="text/javascript">
function calcFactorial(factorialNumber){
var factorialResult = 1;
for(;factorialNumber>0;factorialNumber--) factorialResult *= factorialNumber;
return factorialResult;
}
</script>
</head>
<frameset cols="100%,*">
<frame name="fraCalcFactorial" src="calcfactorial.htm"/>
</frameset>
</html>
Below is the src file
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Example</title>
<script type="text/javascript">
function butCalculate_onclick(){
try{
if (window.top.calcFactorial == null)
throw "This page is not loaded within the correct frameset";
if (document.form1.txtNum1.value == "")
throw "!Please enter a value before you calculate its factorial";
if (isNaN(document.form1.txtNum1.value))
throw "!Please enter a valid number";
if (document.form1.txtNum1.value < 0)
throw "!Please enter a positive number";
}
catch(exception){
if (typeof(exception) == "string"){
if (exception.charAt(0) == "!"){
alert(exception.substr(1));
document.form1.txtNum1.focus();
document.form1.txtNum1.select();
}
else alert(exception);
}
else alert("The following error occurred: " + exception.message);
}
}
</script>
</head>
<body>
<form action="" name="form1">
<input type="text" name="txtNum1" size="3" /> factorial is
<input type="text" name="txtResult" size="25" /><br/>
<input type="button" value="Calculate Factorial"
name="butCalculate" onclick="butCalculate_onclick()" />
</form>
</body>
</html>
This happens because Chrome doesn't allow frames from your hard disk to access each others' content. Which, technically we term as Cross-origin request.
Solution of the above problem is:
1. Either you host your webpage on a local web server. See the following link: What is a faster alternative to Python's http.server (or SimpleHTTPServer)?
2. Use any other browser like Firefox
If you use Visual Studio Code, you can install an extension named "Live Server". It helped me when I had the same problem.
If you don't want to use a local web server as suggested in the accepted answer you can run the browser with cross domain web security / same origin policy disabled.
For Chrome:
Disable same origin policy in Chrome
For Firefox:
Disable cross domain web security in Firefox
https://addons.mozilla.org/en-US/firefox/addon/access-control-allow-origin/
Disable firefox same origin policy
Save the following code as same_server_source.html, run python -m http.server in the same folder, and browse to http://localhost:8000/same_server_source.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>View same server source</title>
</head>
<body>
<iframe id="iframe" src="/" sandbox="allow-scripts allow-same-origin allow-modal"></iframe><br>
<button onclick="alert(iframe.contentWindow.document.body.innerHTML)">View home source</button>
</body>
</html>
I'm testing a web page that hides and unhides a div container when a different one is clicked on. I tested this is Chrome and it worked nicely, but after I put it on my web server I get undefined errors. When I test it in Firefox from the web server, it works fine. It works fine with Chromium in Lubuntu, but Chrome in Windows is giving me an error.
<!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Chrome test</title>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
<script type="text/javascript">
function hideDiv(nameId) {
var grouping = document.getElementById(nameId);
if(grouping.style.display == 'none') {
grouping.style.display = '';
} else {
grouping.style.display = 'none';
}
}
</script>
</head>
<body>
<div id="group">
<div id="header" onclick="hideDiv('failingtoclose');">
<span>Testing</span>
</div>
<div id="failingtoclose">
<span>More testing</span>
</div>
</div>
</body>
</html>
The warning the developer's tools gives me:
'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
and the error:
Uncaught TypeError: Cannot read property 'display' of undefined (Line 9)
The web server is running apache 2.2.22 on Ubuntu.
it's working fine in chrome on windows (version 30.0.1599.69 m) and I doubt it has to do with the server since there is no interaction going on, at least in the code you provide. Changing the doctype to standards mode (<!DOCTYPE html>) might help, since some browsers get confused otherwise (though I doubt chrome does).
I have an exit popup js function which displays an alert and adds something to the url (and redirects) when someone tries to leave the page.
The alert is displayed in all browsers but the code:
window.location.href = "?p=exit"
is not executed in Chrome and IE.
It works fine in Firefox. When you reload the page an alert is displayed and the url is modified.
Take a look at the source code, it is very simple.
Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
var exit=true;
function confirmExit()
{
if(exit)
{
window.location.href = "?p=exit";
}
if(exit)
return "Wait! Don't Leave Empty Handed!\n\nThank you for taking the time to check out our offer! Before you go we have a complimentary crash to help you succeed. Click the 'Cancel' or 'Stay On This Page' button if you're interested!";
}
</script>
</head>
<body onbeforeunload="return confirmExit()">
</body>
</html>
You cannot (cross-browser) redirect from "onbeforeunload".
Chrome blocks alerts set in "onbeforeunload".
Check out this answer for more information:
https://stackoverflow.com/a/7080331/353710
This is similar to this question, although a bit broader.
I'm just opening these pages locally, and they sit in the same folder.
index.html:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<title>TestIndex</title>
<script type="text/javascript">
function init()
{
alert("child.childvar: " + child.childvar); //works in FF, IE, not Chrome
alert("frames['child'].childvar: " + frames['child'].childvar); //works in FF, IE, not Chrome
alert("document.getElementById('child').contentWindow['childvar']: " + document.getElementById('child').contentWindow['childvar']); //works in FF, IE, not Chrome
child.childfunc(); //works in FF, IE, not Chrome
frames['child'].childfunc(); //works in FF, IE, not Chrome
document.getElementById('child').contentWindow['childfunc()']; //doesn't work in anything
}
var parentvar = 7;
function parentfunc()
{
alert("In parentfunc");
}
window.onload = init;
</script>
</head>
<body>
<iframe id="child" name="child" src="child.html">Your browser does not support iframes</iframe>
</body>
</html>
child.html:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<title>TestChild</title>
<script type="text/javascript">
function init()
{
alert("parent.parentvar: " + parent.parentvar); //works in FF, IE, not Chrome
parent.parentfunc(); //works in FF, IE, not Chrome
}
var childvar = 5;
function childfunc()
{
alert("In childfunc");
}
window.onload = init;
</script>
</head>
<body>
</body>
</html>
I can't seem to achieve any communication at all between a page and its iframe's content in chrome. I did read the answers to the question I linked to, but I don't really know what userscripts/content scripts are, so I don't know how relevant that questions was to mine.
I guess my actual question is: how the hell do I get values from an iframe'd page into the parent page!?
Apparently javascript inter-frame communication doesn't work when on the local file system. Put the files on a server and it will likely function as expected.
All the other browsers operate just fine with this, but firefox says 'share is not a function'.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script type="text/javascript">
function share(){
var url = "http://www.facebook.com/sharer.php?u=http://google.com";
var win = window.open(url, "share", "status = 1, height = 500, width = 600, resizable = 0" );
var pollTimer = window.setInterval(function() {
if (win.closed) {
window.clearInterval(pollTimer);
window.location = "http://gmail.com";
}
}, 200);
}
</script>
</head>
<body>
<div id="sharebox">
<img id="share" src="img/share.png" onclick="share();" />
</div>
</body>
</html>
I found the problem. You are not allowed an object with the same id as a function name. I never knew that :s
Without more information this will be impossible to solve, but you may find that the javascript file this function is in had an error, so the parsing stops, then this function also wouldn't be parsed if it is after the part with an error.
Some browsers are more forgiving than others are on errors.
If you use JSLint (http://jslint.com/) to fix the errors that it reports, it may fix your problem.
Otherwise try to use the firebug extension to see where the error may be.