After getting a page's content from an AJAX request I can select tag element but cannot select body element

后端 未结 3 1328
不思量自难忘°
不思量自难忘° 2021-01-26 16:27

I got an html page through an AJAX request

$.ajax({
    async: true,
    method: \'GET\',
    url: linkPage,
    // cache: true,
    success: function (data) {
          


        
相关标签:
3条回答
  • 2021-01-26 17:20

    The reason it doesn't work the way you tried is explained in the jQuery documentation:

    If the HTML is more complex than a single tag without attributes, as it is in the above example, the actual creation of the elements is handled by the browser's .innerHTML mechanism. In most cases, jQuery creates a new <div> element and sets the innerHTML property of the element to the HTML snippet that was passed in.

    Since you can't have a <body> inside a <div>, the browser ignores the <body> tag.

    The documentation goes on to say:

    When passing in complex HTML, some browsers may not generate a DOM that exactly replicates the HTML source provided. As mentioned, jQuery uses the browser's .innerHTML property to parse the passed HTML and insert it into the current document. During this process, some browsers filter out certain elements such as <html>, <title>, or <head> elements. As a result, the elements inserted may not be representative of the original string passed.

    0 讨论(0)
  • 2021-01-26 17:21

    The following jQuery Won't work:

    $(data).find('sustainable');
    

    as the divs are top level elements and data isn't an element but a string, to make it work you need to use .filter

    $(data).filter('sustainable.wrap');
    
    0 讨论(0)
  • 2021-01-26 17:28

    It looks like, when given a string like that, jQuery will only save the contents of the body into its collection:

    const data = `<!DOCTYPE html>
    <html>
    <head>
    ...
    </head>
    <body id="sustainable" class='sustainable'>
    <div id="wrap">
        <main class="temp>
            <section class="sec01">
                ...
            </section>
        </main>
    </div>
    </body>
    </html>`;
    console.log($(data)[0]);
    console.log($(data)[1]);
    console.log($(data)[2]);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

    (Check your browser console. It's selecting the text nodes around #wrap, and #wrap itself, but not the <head> or <body>)

    You could use DOMParser instead, which will try to turn the whole string into a document, without trying to leave things out:

    const data = `<!DOCTYPE html>
    <html>
    <head>
    ...
    </head>
    <body id="sustainable" class='sustainable'>
    <div id="wrap">
        <main class="temp>
            <section class="sec01">
                ...
            </section>
        </main>
    </div>
    </body>
    </html>`;
    const doc = new DOMParser().parseFromString(data, 'text/html');
    console.log(doc.body.className);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

    Another benefit of using DOMParser is that, unlike jQuery, it won't execute possibly-unsafe code in the HTML string:

    const data = `<!DOCTYPE html>
    <html>
    <head>
    ...
    </head>
    <body id="sustainable" class='sustainable'>
    <img src onerror="alert('evil')">
    </body>
    </html>`;
    $(data);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    jQuery version, unsafe

    const data = `<!DOCTYPE html>
    <html>
    <head>
    ...
    </head>
    <body id="sustainable" class='sustainable'>
    <img src onerror="alert('evil')">
    </body>
    </html>`;
    const doc = new DOMParser().parseFromString(data, 'text/html');
    console.log(doc.body.className);
    DOMParser version, safe

    0 讨论(0)
提交回复
热议问题