1

So what I'm doing is, with a super simple PHP proxy that only uses file_get_contents I fetch an HTML and convert it to htmlentities in UTF-8 format. After that with jQuery which is doing the AJAX call I want to get the whole HTML which includes the tags, <html><head><body>code..</body></head></html> into an iframe so then I can traverse it with jQuery in search of inputs. Is there a way to do this? If it can be done some other way that is welcomed too, I'm just doing iframe because I thought that it was the best option. Since it's a complete HTML doc with doctype and everything I think I can't just append it to a div and then traverse it. My jQuery code is as follows:

$(document).ready(function(){

var globalCount = 0;


function countInputs(data, url){
    var unparsedHTML = data.html; // get data from json object which is in htmlentities
    var iframeCreate = $('<iframe id="iframe"></iframe>');
    var iframe = $('#iframe');
    if(iframe.length){
        iframe.remove(); // if iframe exists remove it to clean it
        iframeCreate.insertAfter($('#result'));   //create iframe     
    }else{
        iframeCreate.insertAfter($('#result'));   //create iframe     
    }
    iframe.html(unparsedHTML).text(); // insert html in iframe using html(text).text() to decode htmlentities as seen in some stackoverflow examples
    var inputs = iframe.contents().find('input'); //find inputs on iframe
    var count = inputs.length;
    var output = '';
    globalCount = globalCount + count;
    output = "Count for url: " + url + " is: " + count + " , the global count is: " + globalCount;
    console.log(output);
    $('#result').append(output);
}

/*SNIP ----- SNIP */


function getPage(urls){ 
    console.log("getPage");
    for(i = 0; i < urls.length; i++){
        var u = urls[i];    
        console.log("new request: " + urls[i]);
        var xhr = $.ajax(
        {
            url: "xDomain.php",
            type: "GET",
            dataType: "json",
            data: {
                "url":u
            }
        })

        xhr.done(function(data){
            console.log("Done, starting next function");
            countInputs(data, u)
            });
        xhr.fail(function (jqXHR, textStatus, errorThrown) {
            if (typeof console == 'object' && typeof console.log == 'function') {
                console.log(jqXHR);
                console.log(textStatus);
                console.log(errorThrown);
            }
        });

    }
}

/*SNIP------------SNIP*/

});

The problem is that nothing is ever loaded into the iframe, no error is thrown and the request is successful bringing the HTML in the response. For example if I give the URL http://google.com to the script it should give a count of N inputs back. Since if you go to Google and type in the URL javascript: alert(document.getElementsByTagName('input').length) will alert N number of inputs since there's N inputs. I hope that with the example provided everything is clearer.

Samuel Lopez
  • 2,360
  • 6
  • 29
  • 39

3 Answers3

5

You need to use the contentDocument property of the iframe to put stuff in it.

Also: you need to append your iframeCreate to the document somewhere, otherwise "#iframe" returns nothing.

http://www.w3schools.com/jsref/prop_frame_contentdocument.asp

This answer lets you know about putting everything into the iframe's contentDocument

Example:

var iframe =  $('#iframe');
var idoc = iframe[0].contentDocument;
idoc.open();
idoc.write(mytext);
idoc.close();
Community
  • 1
  • 1
Jared Forsyth
  • 12,808
  • 7
  • 45
  • 54
  • I will try this answer too, about the "append my iframeCreate" won't the insertAfter function of jQuery act as append (`iframeCreate.insertAfter($('#result')); //create iframe`)? do I need to create a div and append the iframe to that div or what did you mean by append? – Samuel Lopez Apr 24 '13 at 18:31
2

doing server job on the client side? Not the brightest idea imho. I think the reason why you are doing this is because you want to manipulate the dom with jquery(maybe simplexml doesn't seem appealing to you?). In this case i suggest looking at http://querypath.org/ . it's jquery for the server.

Twisted1919
  • 2,430
  • 1
  • 19
  • 30
  • So I took your advice and I'm doing the job on the server side, it's much easier as you said, with DOM. I did not know that you could manipulate DOM with PHP creating a new this answer helped me a lot [Count all HTML tags in page PHP](http://stackoverflow.com/questions/3184284/count-all-html-tags-in-page-php), although I'm using your answer as a method I marked the other one the real answer since that did what I was asking for. But this tip is great and the real way to do what I want. Thanks! – Samuel Lopez Apr 25 '13 at 13:58
  • I don't really care which answer was marked as long as you get your job done in a correct way :) – Twisted1919 Apr 25 '13 at 14:13
0

I've noticed that if you put HTML into an iframe, it will be encoded. If the iframe contains an immediately descending input, calling $("iframe input").length would return 0.

If you were to use a div instead, the HTML wouldn't be encoded, allowing you to count the number of elements:

$(document).ready(function() {

    //works :)
    console.log("inputs in div: " + $("div input").length);

    //returns 0
    console.log("inputs in iframe: " + $("iframe input").length);
});

Run it on jsFiddle.

Other than that I don't see a problem, although I'd also fetch the HTML on the client side if you can overcome cross-domain restrictions (can't think of how you'd do that thus far).

James Wright
  • 3,000
  • 1
  • 18
  • 27
  • I did try it like this, but I believe that since the HTML has a Doctype declared, CSS, Javascript and HEAD there's some kind of mixture between the actual page and the new page and because of that the DOM is never completely loaded. – Samuel Lopez Apr 26 '13 at 18:16