22

What I'm trying to do seems simple: get an HTML page through $.ajax() and pull out a value from it.

$(function () {
    $.ajax({
        url: "/echo/html",
        dataType: "html",
        success: function (data) {
            $('#data').text(data);
            $('#wtf').html($(data).find('#link').text());
        },
        data: {
            html: '<!DOCTYPE html><head><title><\/title><link href="../css/popup.css" rel="stylesheet" /><\/head><body><ul><li><a id="link">content<\/a><\/li><\/ul><\/body><\/html>'
        }
    });
});

The problem is that jQuery refuses to parse the returned HTML.

The fiddle I'm play with this in isn't working in the mean time, so there's little else I can do to provide a working example.

UPDATE: My new fiddle is working fine, but it seems the problem is that in my actual project I'm trying to parse a large, complex bit of HTML. Is this a known problem?

Stephen Collins
  • 3,523
  • 8
  • 40
  • 61
  • You need to use POST when using `/echo/html/` on jsFiddle (note the trailing slash, too). http://jsfiddle.net/hcrM8/6/ – gen_Eric Nov 15 '13 at 18:37

7 Answers7

20

Your code works fine. You just aren't using jsFiddle's API correctly. Check the docs for /echo/html/ (http://doc.jsfiddle.net/use/echo.html#html):

URL: /echo/html/

Data has to be provided via POST

So, you need to update your AJAX call to use POST. Also the trailing slash is needed.

$(function () {
    $.ajax({
        url: "/echo/html/",
        type: "post",
        dataType: "html",
        success: function (data) {
            $('#data').text(data);
            $('#wtf').html($(data).find('#link').text());
        },
        data: {
            html: '<!DOCTYPE html><head><title><\/title><link href="../css/popup.css" rel="stylesheet" /><\/head><body><ul><li><a id="link">content<\/a><\/li><\/ul><\/body><\/html>'
        }
    });
});

DEMO: http://jsfiddle.net/hcrM8/6/

Community
  • 1
  • 1
gen_Eric
  • 223,194
  • 41
  • 299
  • 337
  • Then the problem must lie in the actual HTML I'm fetching in my project. It's very large and very complex. The thing is, if jQuery can parse the page when it exists within the page, why can't it parse the page returned from the AJAX request? – Stephen Collins Nov 15 '13 at 18:50
  • 2
    @wtfsven: What happens on your *real* page? What do you see? Any errors? When doing `$(data)`, jQuery strips out the ``, ``, and `` tags. Your jQuery object looks like: `[, <link/>, <ul>]`. Is the HTML on your real page valid? You may also need `.filter` vs. `.find` depending on its structure.</ul> – gen_Eric Nov 15 '13 at 18:54
  • Ok, so it turns out for some reason jQuery is finding one iframe (that's what i'm selecting for), and not another. I'm still looking into it, but it seems to be working for the time being. – Stephen Collins Nov 15 '13 at 19:00
  • It's old, but I comment because it's the top voted answer and the problem hopefully is solved here: https://stackoverflow.com/a/12848798/2590616 – RiZKiT Jan 12 '18 at 14:45
  • 1
    @RocketHazmat - `.filter` vs `.find` was all I needed. You don't know what you don't know. Thanks mate! :) – Luke Oct 13 '21 at 06:02
8

If you would like to parse it, jquery has a nifty trick :)

 ParsedElements = $(htmlToParse);
 Console.log(ParsedElements);

You now have DOM elements you can traverse without placing them in the body of the document.

Krish R
  • 22,583
  • 7
  • 50
  • 59
Anthony Iacono
  • 203
  • 1
  • 9
  • 3
    But that's just the problem. It's not parsing the HTML at all. `$('#wtf').html($(data).find('#link').text());` should return "content", but it's saying `text()` is undefined. – Stephen Collins Nov 15 '13 at 18:16
3

jQuery.parseHTML()

http://api.jquery.com/jQuery.parseHTML/

str = "hello, <b>my name is</b> jQuery.",
  html = $.parseHTML( str ),
  nodeNames = [];

// Gather the parsed HTML's node names
$.each( html, function( i, el ) {
  nodeNames[ i ] = "<li>" + el.nodeName + "</li>";
});

Some thing is wrong with your ajax on fiddle

http://jsfiddle.net/hcrM8/5/

var html= '<!DOCTYPE html><head><title><\/title><link href="../css/popup.css" rel="stylesheet" /><\/head><body><ul><li><a class="disabled" id="link">content<\/a><\/li><\/ul><\/body><\/html>';
            h = $.parseHTML(html);
            $('#data').text(h);
            $('#wtf').html($(h).find('#link').text());
Rizwan Mumtaz
  • 3,875
  • 2
  • 30
  • 31
2

Why don't you just use the load method?

$( "#wtf" ).load( "/echo/html #link" );

Or, here's your fiddle fixed and working:

http://jsfiddle.net/hcrM8/4/

dave
  • 62,300
  • 5
  • 72
  • 93
  • Because that's not what I'm doing in my project. I'm reaching out to grab a page, pull some data from it, then throwing it away. – Stephen Collins Nov 15 '13 at 18:14
1

I had the same problem and i fixed encapsulating requested html code into just one container element.

Bad Example:

<a href="link">Linkname</a>
<p>Hello world</p>

Jquery couldnt convert this to element, because it wishes to convert a single element tree. But those are not having a container. Following example should work:

Right Example:

<div>
    <a href="link">Linkname</a>
    <p>Hello world</p>
</div>
wmwmwm
  • 91
  • 3
1

All answers do not point to the real problem, jQuery seems to ignore the head and body tag and creates an array of nodes. What you normally want is, extract the body and parse it.

Take a look at this helpful answer, I do not want to copy his work: https://stackoverflow.com/a/12848798/2590616.

RiZKiT
  • 2,107
  • 28
  • 23
0

I am facing the same problem, and it is not because you are doing something wrong.

it's because the "link" tag is not supposed to have any innerHTML returned, it's explicitly excluded in jquery, you will find some where this line:

rnoInnerhtml = /<(?:script|style|link)/i,

This tag in HTML is supposed to link to external style sheet.

Hkachhia
  • 4,463
  • 6
  • 41
  • 76
ZMs
  • 9
  • 1