Iframe, onload and document. domain

Source: Internet
Author: User

Link: http://www.nczonline.net/blog/2009/09/15/iframes-onload-and-documentdomain/
Translator: Demix

In the era of web, more and more people are paying attention to using iframe to embed content from third-party websites into their own websites. When javascript can perform data interaction through its domain name, iframe starts to provide a series of security measures, making it impossible for a third-party website nested in iframe to obtain the script program of the main website. This cross-origin restriction also makes the parent page unable to read the nested content script. From all perspectives, the parent page is completely unrelated to the page contained by iframe. This complex relationship makes javascript Object ownership one of the many topics about iframe.

Iframe and ownership

The iframe element is located in the parent page, so you can use and operate it like a normal element. Indicates that the window object of iframe content is added to iframe as a page attribute. To enable the parent page to obtain the iframe window object in an appropriate way, the domain names of the parent and iframe pages should be consistent (details ).

When the domain name matches, the parent page can obtain the iframe window object. The iframe element has the attribute contentDocument. This attribute contains the document Object of the iframe object, so we can use the parentWindow attribute to retrieve the window object. This has become a standard method for obtaining iframe window objects and is supported by most browsers. The browser before ie8 does not support this attribute. We need to use its proprietary contentWindow attribute. For example

1 function getIframeWindow (iframeElement ){
2 return iframeElement. contentWindow | iframeElement. contentDocument. parentWindow;
3}
In addition, the window object of the parent page can be obtained using window. parent in iframe. The iframe element can also use window. frameElement to obtain its own reference. Because iframe is contained by a parent element but can directly obtain the window object of iframe, this method is widely used to break through the boundaries between the two.

Onload event using iframe element

It is an interesting experiment to determine when the iframe is loaded due to different ownership. Non-ie browsers provide many useful methods. They give the iframe element a load event, so that we can determine when the iframe is fully loaded. Because the iframe element is included in the parent page, you do not have to worry about cross-origin restrictions. The iframe for loading local data can be the same as the iframe for loading external data to complete the event. Example:

1 var iframe = document. createElement ("iframe ");
2 iframe. src = "simpleinner.htm ";
3 iframe. onload = function (){
4 alert ("Iframe is now loaded .");
5 };
6 document. body. appendChild (iframe );
The preceding example applies to all non-ie browsers. I tried to use the attachEvent method, but I finally found that ie does not support load events on iframe.

Onload event of the window object using iframe

It seems that ie is going to create problems for us again. However, I remember that I have never considered referencing an external file in iframe. In my experiment, I used to process content under the same domain name. Because the cross-origin restriction does not exist, I can easily obtain the window object of the iframe object and add the onload event. For example:

1 var iframe = document. createElement ("iframe "),
2 iframeWindow;
3 iframe. src = "simpleinner.htm ";
4 document. body. appendChild (iframe );
5 iframeWindow = iframe. contentWindow | iframe. contentDocument. parentWindow;
6 iframeWindow. onload = function (){
7 alert ("Local iframe is now loaded .");
8 };

Interestingly, you must add the iframe element to the page before registering an event. If it is prior to it, the iframe window object will not exist, and we certainly cannot register the event on the window object. This method is only effective for two nested pages in the same domain in ie and ff. Other Browsers Do not create window objects and will throw an exception.

Define document. domain

I tried to find a method to listen to iframe load events in ie and more methods to be applied to other browsers, So I continued my experiment. Next, because I have multiple pages of different second-level domain names that need to be read using iframe, I set the document. domain of the parent page. Setting document. domain as the primary domain name allows communication between these iframe and the parent page. For example, if I want to read an iframe with the address www2.nczonline.net, it is technically not allowed. However, if I set document. domain to 'nczonline. net' on both the parent and iframe pages, the two pages can communicate with each other. As follows:

1 document. domain = "nczonline.net ";
This statement eliminates the differences between domain names. We can process these two pages just like two websites with the same domain name.

There was another problem. Before iframe is fully loaded, it will be considered to belong to the page of the src attribute flag declared in the iframe label. The relative address is automatically added with the address of the parent page (www.nczonline.net) and is in conflict with the document. domain we set. This means that when comparing nczonline.net and www.nczonline.net, we will not pass the same domain check, so when we try to get the iframe window object, it will cause javascript errors. The iframe page does not change its associated domain value until it is loaded, and the script that changes the domain value will be executed. When the iframe has been loaded, everything runs perfectly. But how do we know when iframe will be loaded?

Think differently

Since consistency does not find a way to determine whether the iframe has been loaded across browsers, I decided to change my mind. If we ask iframe to tell the parent page that it has been loaded, rather than asking the parent page to obtain the iframe load event, the problem may be solved. I hope this method is as simple as registering an event handle, so I used the following idea: I declare a method on the iframe element, and then, this function is executed after the iframe page is loaded. Of course, this method is declared to the iframe element itself rather than the iframe window object. The latter method has been proven to be incompatible with all browsers in the previous study. The result looks like this:

1 var iframe = document. createElement ("iframe ");
2 iframe. src = "simpleinner.htm ";
3 iframe. _ myMethod = function (){
4 alert ("Local iframe is now loaded .");
5 };
6 document. body. appendChild (iframe );
The above Code declares the _ myMethod method on the iframe element. Add the following method to the page in iframe:

1 window. onload = function (){
2 window. frameElement. _ myMethod ();
3}
Since the above Code runs after we declare document. domain, we do not have to worry about any security restrictions. This method works perfectly under the same primary domain name. It is compatible with all browsers, which is exactly what I need. However, it is still bothering me to listen to the iframe load events that contain third-party pages.

Onreadystatechange using iframe

I decided to study the iframe interface document of IE browser. If we declare in the onload event that some events obviously cannot achieve the desired effect, I think there will certainly be a similar method. I tried to add the event handle using the attachEvent method, but it still didn't work. OK. Obviously, iframe in ie does not support load events. Is there any other method?

Next I used the readystatechange event, a weird method of ie. Obviously, it is completely different from the readystatechange event of the xhr object. I want to know whether the iframe element also supports this event. It will change to 'interactive 'before the nested content of iframe is loaded completely, and then to 'complete '. At the same time, because it is registered to the iframe element rather than the iframe window object, this naturally does not have cross-origin issues. The code I finally compiled is as follows:

1 var iframe = document. createElement ("iframe ");
2 iframe. src = "simpleinner.htm ";
3
4 if (navigator. userAgent. indexOf ("MSIE")>-1 &&! Window. opera ){
5 iframe. onreadystatechange = function (){
6 if (iframe. readyState = "complete "){
7 alert ("Local iframe is now loaded .");
8}
9 };
10} else {
11 iframe. onload = function (){
12 alert ("Local iframe is now loaded .");
13 };
14}
15
16 document. body. appendChild (iframe );
Judging whether the browser is an IE browser is a little troublesome. Originally, I prefer to use the browser to check whether iframe. readystate exists. However, an error is thrown when you try to obtain the iframe attribute that is not added to the page. I also tried to use document. readyState to determine whether to use readystatechange. However, many browsers already support the previous attribute, so it is not an effective method of division.

Internet Explorer's support for onload events

In a short time after this article, Christopher commented that using attachEvent on the iframe element can work in ie. I swear that I have tried this method before, but I tried another experiment due to his prompt. Then I found that he was correct. Then I studied the document on msdn and finally found a document to illustrate this problem. It eventually makes our code look like the following:

1 var iframe = document. createElement ("iframe ");
2 iframe. src = "simpleinner.htm ";
3
4 if (iframe. attachEvent ){
5 iframe. attachEvent ("onload", function (){
6 alert ("Local iframe is now loaded .");
7 });
8} else {
9 iframe. onload = function (){
10 alert ("Local iframe is now loaded .");
11 };
12}
13
14 document. body. appendChild (iframe );
The above code can still run on all browsers and avoid potential conflicts between the readystatechange event and the load event.

Comprehensive

After a short investigation, we found that a cross-browser method existed to determine when an iframe object was loaded. This makes listening and Error Control for iframe much easier. Thanks to all browser vendors for seeing the benefits of adding these events to the iframe element, rather than relying on the iframe window object or believing that we do not usually care about when the iframe will be loaded.

I haven't translated it for a long time. I have made many mistakes when I translated the above article. Zakas is a funny article. A few minutes later, someone posted a message saying that there was an error in the article and they got rid of it again. Here we can see a benefit of blog writing-growth together. Without subsequent comments, Zakas may have been able to monitor the readystatechange event elegantly. In addition, through this article, we can see the details of the master. Although the problems described in the entire article may be exposed to us at ordinary times, another person may be so meticulous. This is also true for PPK, and for the old saying that this is true for all masters. Success focuses on details.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.