I got an html page through an AJAX request
$.ajax({
async: true,
method: \'GET\',
url: linkPage,
// cache: true,
success: function (data) {
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 theinnerHTML
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.
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');
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