This question already has answers here:
How to use JavaScript to access cross domain iFrame content?
(6 answers)
Closed 6 years ago.
I like to download the html code via JavaScript. This HTML-Code is an extern webpage which will be displayed in iframe. Is it possible to get HTML-Code how it is displayed in this iframe.
So here is my try:
<body>
<iframe id="iframe_htmlcode1" name="iframe_htmlcode" src="http://www.w3schools.com"></iframe>
<textarea id="TextArea1" name="S1"></textarea>
<script>
function getAndSetContent() {
var x = document.getElementById("iframe_htmlcode1");
var y = (x.contentWindow || x.contentDocument);
document.getElementById("TextArea1").value = y.documentElement.innerHTML;
}
</script>
<input id="Button1" type="button" value="button" onclick="getAndSetContent()" />
But y.documentElement.innerHTML returns nothing. I've tried it also with a local html document which will be used in the iframe, which works fine.
Any suggestions?
THANKS
I assume that your code is working with the local file because the protocols are matching, anyway the debug says it all (you will need some basic server and then try again).
Uncaught SecurityError: Blocked a frame with origin "null" from accessing a frame with origin "http://www.w3schools.com". The frame requesting access has a protocol of "file", the frame being accessed has a protocol of "http". Protocols must match.
Once you get your code on the server you may need to use something like the below to get around the cors issues
https://github.com/padolsey-archive/jquery.fn/tree/master/cross-domain-ajax
Related
I have this piece of code. I can see the iframe content but it seems that edp0 is always undefined. Why?
<!DOCTYPE html><html>
<body>
<iframe src="DOM-copyB.html"></iframe>
<script>
ed = document.getElementsByTagName('iframe')[0].contentDocument;
edp0 = ed.getElementsByTagName('p')[0];
edp1 = ed.getElementsByTagName('p')[1];
alert(edp0);
</script>
</body></html>
Here is DOM-copyB.html:
<!DOCTYPE html><html><head></head>
<body>
<p>A<b>B</b>C</p>
<p>1<b>2</b>3</p>
</body></html>
Your JavaScript is probably running before the iframe's content is loaded. Try running your code in window.onload and see if that helps:
window.onload = function() {
ed = document.getElementsByTagName('iframe')[0].contentDocument;
edp0 = ed.getElementsByTagName('p')[0];
edp1 = ed.getElementsByTagName('p')[1];
alert(edp0);
};
If you're not running the code from a server, though, I suspect after you get the code to successfully reference the iframe content, you'll get an error like this in the Chrome console due to Cross-Origin security:
Uncaught SecurityError: Failed to read the 'contentDocument' property from 'HTMLIFrameElement': Blocked a frame with origin "null" from accessing a frame with origin "null". Protocols, domains, and ports must match.
If you run them from a server, that error should go away. See this question for more details on that:
Using iframe with local files in Chrome
I'm not sure about javascript. But jusing jQuery would be much easier:
<iframe src="DOM-copyB.html" id="myFrame"></iframe>
<script>
$("#myFrame").contents().find("p");
</script>
I am trying to understand the same origin policy of browsers. Theoretically things seem ok. So i am now trying to practically understand it using a small demo.
I have 2 domains hosted on wamp, viz domain1.com and domain2.com
domain1.com consists of index.php, innocent.php and 2 js files in a javascript folder, namely dom1_javascript.js and dom1_normal.js
here are the details of the above files: -
index.php
<?php
$value = "domain 1 cookie";
// send a simple cookie
setcookie("Dom1Cookie",$value);
?>
<html>
<script type="text/javascript" src="../javascript/dom1_javascript.js">
</script>
<body>
this is from doamin 1
</body>
</html>
innocent.php
<?php
$userSecret=$_GET['userCreds'];
if($userSecret)
{
echo "the user's secret is "+$userSecret;
}
else
{
echo "sorry user secret not found";
}
?>
dom1_javascript.js
alert(document.cookie);
dom1_normal.js
alert("alert domain 1");
alert(document.cookie);
//referring the div
var bdy=null;
// creating the form
var secretForm=document.createElement("form");
secretForm.id="goodForm";
secretForm.method="get";
var myQryStr="http://domain1.com/innocent.php?userCreds=abcd";
alert(myQryStr);
secretForm.action=myQryStr;
//creating the text box in the form
var hiddenBox=document.createElement("input");
hiddenBox.type="text";
hiddenBox.name="secBox";
hiddenBox.value="abhinav";
//appending the box to the form
secretForm.appendChild(hiddenBox);
//appending the form to the div
bdy=document.getElementById("mydiv");
alert(bdy);
bdy.appendChild(secretForm);
//submitting the form
document.getElementById("goodForm").submit();
domain2.com consists of 2 versions of index.php, viz, index.php and index1.php
here are the details of the above php file: -
index.php
<?php
$value = "domain 2 cookie";
// send a simple cookie
setcookie("Dom2Cookie",$value);
?>
<html>
<head>
<script type="text/javascript" src="http://domain1.com/javascript/dom1_javascript.js">
</script>
</head>
<body>
<div id="mydiv">
<img src="http://domain1.com/images/dom1.bmp"/>
this is from doamin 2
</div>
</body>
</html>
index1.php
<?php
$value = "domain 2 cookie";
// send a simple cookie
setcookie("Dom2Cookie",$value);
?>
<html>
<head>
<script type="text/javascript" src="http://domain1.com/javascript/dom1_normal.js">
</script>
</head>
<body>
<div id="mydiv">
<img src="http://domain1.com/images/dom1.bmp"/>
this is from doamin 2
</div>
</body>
</html>
I am using firefox as the browser to test these scritps.
First I goto domain1.com in the browser. This sets the domain1 cookie. Then I goto domain2.com/index.php
As expected, the script on domain2/index.php sets the domain2 cookie. Then the javascript from domain1 gets loaded which says
alert(document.cookie)
The execution of this script alerts the domain2 cookie value.
Assumption1: -
So my understanding here is that due to the same origin policy of the browser, even though the script was called from domain1, it did not alert the domain1 cookie, but instead alerted the domain2 cookie.
Please let me know if I am correct in the above assumption ?
Now I clear the browser cache and remove all the cookies from the browser. Run domain1.com again, which again sets domain1 cookie. And then, this time I goto domain2.com/index1.php which sets the cookie for domain2 and then accesses the script present in
domain1.com/javascript/dom1_normal.js
Now if my assumption1 was correct,( i.e. a javascript from domain1.com when imported in domain2.com will get executed with reference to domain2 only, and not its incoming domain, as per the same origin policy) then in this case also it should be the same with dom1_normal.js. So the javascript in dom1_normal.js should have access to all the HTML elements in domain2/index1.php It does not really so happen as confirmed by
bdy=document.getElementById("mydiv");
alert(bdy);
in domain1.com/javascript/dom1_normal.js which alerts null
please let me know where am i going wrong. And i have gone through more than a dozen discussions (on stack overflow and elsewhere including MDN, wiki, google etc.) and articles about same origin policy, but none of it has made the idea clear to me.
The Same-Origin policy doesn't have much to do with loading JavaScript. Regardless of where a script comes from, its actions take place under the aegis domain of the main page. Thus, if your main page comes from "domain1", then all scripts execute in the context of "domain1", whether they came from that domain or any other domain.
Note that it's not possible to access the source code of a script that loads from some other domain.
The reason your "dom1_normal" script reports "null" for that element reference is probably because you're importing the script before the <body>. The DOM is built incrementally, but scripts run synchronously when they're loaded, so if you call getElementById() for some element that's after the <script> tag, it won't be there.
I want to create a iframe without src ( about:blank ) but that iframe content some javascript html
I need to do it because I don't want create a hosted webpages on server for this mission, this will make more connection to server which are no good for resource. And also don't want to write direct javascript html on webpage because they make the webpage load slow most time when load/running.
How to do it by using javascript (jquery maybe )?
iframe eg :
<iframe src="about:blank" width="300" height="250" scrolling="no" frameborder="0" marginwidth="0" marginheight="0" ></iframe>
and its content:
<div>xxx</div>
<script type="text/javascript">var abc=1 </script>
<script type="text/javascript" src="http://1234.net/js.js"></script>
UPDATE
Thanks for some answered following.
But I need to clarify that script will create iframe by javascript also, because the need to create iframes in one page with different ids.
Please look at my test:
http://jsfiddle.net/rDkEw/
The problems are:
if use document.body.appendChild, the iframe will create on body of webpage, but I need it to keep it inside the current div which hold the JavaScript.
For everyone googling this after 2016: Use a data: URL, URLs prefixed with the data: scheme, allow content creators to embed small files inline in documents.
<iframe src="data:text/html, <h1>Your HTML</h1>"></iframe>
An <iframe> has a contentDocument property representing its… content’s document. You can use write() on that. Here’s a demo.
You can do it like this:
var iframe = document.getElementById('iframeid');
var div_el = document.createElement('div');
div_el.innerHTML = "....";
iframe.contentWindow.document.body.appendChild(div_el);
A jQuery solution:
$('#iframeid').contents().find('body').append("<div>.....</div>");
With jQuery:
$('#myIframe').appendTo('#iframeDiv');
your iframe id = "myIframe"
your html content div id = "iframeDiv";
note: without jQuery, the two other answers seem perfectly suited.
You can add any content to page in iframe as described here but as you don't have a page loaded I doubt the javascript you add to this page will work. You can give it a try.
I want to use Jquery or javascript to get the raw content (mean everycharacter) of an Iframe. It sounds simple but I'm still struggling with finding the right way for it.
For now it is only a XML content in the Iframe though.
Here the code:
$(function() {
var xmlContent = $("#CFrame").contents().find("*").text();
// The magic
$('#SResult').xslt({xml: xmlContent, xslUrl: 'stylesheet/designSS.xsl'});
});
The html page
<form id="searchForm" method="GET" target="ContentFrame" action="http://125.235.8.210:380/search" onSubmit="processContent()">
.....
</form>
</div>
<div id="SResult">
</div>
<iframe id="CFrame" name="ContentFrame" frameborder="1" height="2000px" width="1000px" scrolling="no" src="stylesheet/test.xml"></iframe>
</body>
Thanks,
Disclaimer: I'll answer your question regardless of whether it is actually an elegant solution to your problem. Joseph seems to take that as the question. I would say he is probably right to do so.
It won't work trying to get the frame using mimetype text/xml. The browser will proceed and 'translate' the XML into HTML. That's why it doesn't sound so simple. This way it is actually impossible.
I present you with a simple work-around for this problem.
<html>
<head>
<script>
function getXmlContents() {
/*
Note: Because of security reasons, the contents of a document can be accessed from another document only if the two documents are located in the same domain.
http://www.w3schools.com/jsref/prop_frame_contentdocument.asp
*/
var iframeDocument = document.getElementById('greetingFrame').contentDocument;
if (iframeDocument == null)
return undefined;
var xmlContainer = iframeDocument.getElementById('xmlContainer');
if (xmlContainer == null)
return undefined;
return xmlContainer.innerText == null ? xmlContainer.textContent : xmlContainer.innerText;
};
</script>
</head>
<body>
<iframe id="greetingFrame" src="helloworld.html" onload="alert(getXmlContents())">
</iframe>
</body>
</html>
The contents of the XML are wrapped inside an HTML (helloworld.html):
<html>
<body>
<script id="xmlContainer" type="text/xml">
<?xml version="1.0" encoding="UTF-8"?>
<title>
Hello world
</title>
</script>
</body>
</html>
I've successfully tested this in Chrome, Firefox and IE.
Of course you would have to wrap your XML documents inside a HTML script tag as indicated above. The XML can also be wrapped in a different tag, if you'd like it rendered for example, but you'd have to encode the XML using html encoding. This needs to be done on the server-side. A very simple (php/ruby/python/etc) script would suffice.
If your XML resides on your domain, you are better off with AJAX, especially using the jQuery library, which parses it for you and make it ready for immediate manipulations.
If it does not live on your domain, then you can't access it via AJAX unless the remote server and your client's browser both support CORS.
You have options though:
If the remote server's API supports JSONP, use it instead of XML. Then you can use jQuery to retrieve JSONP data or roll your own script loader.
Or use your server to proxy the XML for you. Servers are not restricted to the Same Origin Policy. Create an API on your server that relays your form data to the remote server and retrieve the remote page - all as if your server was the browser. Then forward the results back to you.
I have the following code for viewing my webcam directly via a publicly accessible link.
<!DOCTYPE html>
<html>
<head>
<title>webRTC Test</title>
</head>
<script type = "text/javascript">
function init()
{
if(navigator.webkitGetUserMedia)
{
navigator.webkitGetUserMedia({video:true}, onSuccess, onFail);
}
else
{
alert('webRTC not available');
}
}
function onSuccess(stream)
{
document.getElementById('camFeed').src = webkitURL.createObjectURL(stream);
var src = document.getElementById('camFeed').getAttribute('src');
document.getElementById('streamLink').href = src;
}
function onFail()
{
alert('could not connect stream');
}
</script>
<body onload = "init();" style="background-color:#ababab;">
<div style="width:352px; height:625px; margin:0 auto; background-color:#fff;">
<div>
<video id ="camFeed" width="320" height="240" autoplay>
</video>
</div>
<div>
<canvas id="photo" width="320" height="240">
</canvas>
</div>
<div style="margin: 0 auto; width:82px;">
<a id="streamLink">Visit Stream</a>
</div>
</div>
</div>
</body>
</html>
The link generated in the anchor tag is something like:
blob:http%3A//sitename.com/7989e43a-334r-4319-b9c5-9dfu00b00cd0
And upon visiting chrome tells me "Oops! This link appears to be broken."
Help appreciated!
The File API spec defines URL.createObjectURL. There are a couple of sections that make what you're trying to do impossible in a browser that follows the spec.
Section 11.5 says:
The origin of a Blob URI must be the origin of the script that called URL.createObjectURL. Blob URIs must only be valid within this origin.
In other words, the URIs returned by createObjectURL can only be used within the context of the website that created them (see RFC6454: The Web Origin Concept for a more precise definition of what the HTML specs mean by “origin”). You can't visit a URL returned by createObjectURL directly.
Section 11.6 says:
This specification adds an additional unloading document cleanup step: user agents must revoke any Blob URIs created with URL.createObjectURL from within that document.
This means that even if you could visit the URL directly, as soon you you leave the page that called createObjectURL the URL that was created ceases to exist.
You must ensure that you’re using/testing your code at HTTP or HTTPs protocols --- because URL.createObjectURL has some issues at file:// protocol --- and it can’t be able to generate right BLOB for your video while using file:// ---- !!!
Your code won't work on localhost or your machine alone.
All you need is, upload this HTML document on the Net(just in case you are wondering on how to get Hosting for yourself, then try checkout Dropbox, you can upload your HTML page publicly and get access via Public Link for free or try some other product or simply get hosting for yourself). As you can see that this example http://www.html5rocks.com/en/tutorials/getusermedia/intro/ works perfectly in chrome, though the code that it is utilising is the same as yours. I hope this solution is of some help to your and others searching for an answer to this bug.
Also, you can then use an iframe to get access to the video element to perform operations on it.