Найти тег body в ответе ajax HTML

Я делаю ajax-вызов для извлечения контента и добавления этого контента следующим образом:

$(function(){
    var site = $('input').val();
    $.get('file.php', { site:site }, function(data){
        mas = $(data).find('a');
        mas.map(function(elem, index) {
            divs = $(this).html();
            $('#result').append('' + divs + '');
        })
    }, 'html');
});

Проблема в том, что когда я меняю a в body Я ничего не получаю (без ошибок, просто без HTML). Я предполагаю, что тело - это тег, похожий на 'a'? Что я делаю неправильно?

Так что это работает для меня:

 mas = $(data).find('a');

Но это не так:

 mas = $(data).find('body');

4 ответа

Решение

Разбор возвращенного HTML через объект jQuery (т.е. $(data)) чтобы получить body тег обречен на провал, боюсь.

Причина в том, что возвращенный data это string (пытаться console.log(typeof(data))). Теперь, согласно документации jQuery, при создании объекта jQuery из строки, содержащей сложную разметку HTML, используются такие теги, как body могут быть раздеты. Это происходит потому, что для создания объекта HTML-разметка фактически вставляется в DOM, который не может разрешить такие дополнительные теги.

Соответствующая цитата из документации:

Если строка передается в качестве параметра в $(), jQuery проверяет строку, чтобы увидеть, выглядит ли она как HTML.

[...] Если HTML является более сложным, чем отдельный тег без атрибутов, как в приведенном выше примере, фактическое создание элементов обрабатывается механизмом innerHTML браузера. В большинстве случаев jQuery создает новый элемент и присваивает свойству innerHTML элемента тот фрагмент HTML, который был передан. Когда параметр имеет один тег (с необязательным закрывающим тегом или быстрым закрытием) - $( "") или $( ""), $( "") или $( "") - jQuery создает элемент с помощью встроенной функции JavaScript createElement().

При передаче сложного HTML некоторые браузеры могут не генерировать DOM, который точно копирует предоставленный исходный код HTML. Как уже упоминалось, jQuery использует свойство браузера.innerHTML для анализа переданного HTML-кода и вставки его в текущий документ. Во время этого процесса некоторые браузеры отфильтровывают определенные элементы, такие как элементы , или <head> В результате вставленные элементы могут не соответствовать исходной переданной строке.</p></blockquote> </div> <div class="a-info"> <div class="row"> <div class="col-sm-2"> <a class="like-button" title="Чтобы оценить ответ необходимо войти под своим логином." > <div class="btn btn-my btn-block" style="background: #bdc3c7 "> <span itemprop="upvoteCount">12</span> <i class="far fa-thumbs-up"></i> </div> </a> </div> </div> <div class="row"> <div class="col-sm-4"> <a class="a-source" href="https://stackoverflow.com/questions/14423257/find-body-tag-in-an-ajax-html-response/14423290#14423290" target="_blank">Источник</a> <a class="a-share" href="https://stackru.com/questions/31438706/najti-teg-body-v-otvete-ajax-html/31438733#31438733" itemprop="url">Поделиться</a> </div> <div class="col-sm-8 text-right author" itemprop="author" itemscope="" itemtype="http://schema.org/Person"> <span itemprop="name"> <a href="https://stackoverflow.com/users/1889273/user1889273" class="q-user" rel="noopener" target="_blank">user1889273</a> </span> <span class="q-date" title="2013-01-20 09:39"> 20 янв '13 в 09:39</span> <span class="hidden" itemprop="dateCreated" datetime="2013-01-20 09:39">2013-01-20 09:39</span> </div> </div> </div> <span class="hidden" itemprop="dateCreated" datetime="2013-01-20 09:39">2013-01-20 09:39</span> </div> </div> <div id="31438738" class="answer " itemscope itemtype="http://schema.org/Answer" itemprop="suggestedAnswer"> <div class="a-body"> <div class="a-text" itemprop="text"> <p>Я закончил с этим простым решением:</p><pre><code>var body = data.substring(data.indexOf("<body>")+6,data.indexOf("</body>")); $('body').html(body); </code></pre><p>Работает также с <strong>головой</strong> или любым другим <strong>тегом</strong>.</p><p>(Решение с синтаксическим анализом xml было бы лучше, но с недопустимым ответом XML вы должны выполнить некоторый "синтаксический анализ строки".)</p> </div> <div class="a-info"> <div class="row"> <div class="col-sm-2"> <a class="like-button" title="Чтобы оценить ответ необходимо войти под своим логином." > <div class="btn btn-my btn-block" style="background: #bdc3c7 "> <span itemprop="upvoteCount">13</span> <i class="far fa-thumbs-up"></i> </div> </a> </div> </div> <div class="row"> <div class="col-sm-4"> <a class="a-source" href="https://stackoverflow.com/questions/14423257/find-body-tag-in-an-ajax-html-response/35157782#35157782" target="_blank">Источник</a> <a class="a-share" href="https://stackru.com/questions/31438706/najti-teg-body-v-otvete-ajax-html/31438738#31438738" itemprop="url">Поделиться</a> </div> <div class="col-sm-8 text-right author" itemprop="author" itemscope="" itemtype="http://schema.org/Person"> <span itemprop="name"> <a href="https://stackoverflow.com/users/1479958/user1479958" class="q-user" rel="noopener" target="_blank">user1479958</a> </span> <span class="q-date" title="2016-02-02 15:44"> 02 фев '16 в 15:44</span> <span class="hidden" itemprop="dateCreated" datetime="2016-02-02 15:44">2016-02-02 15:44</span> </div> </div> </div> <span class="hidden" itemprop="dateCreated" datetime="2016-02-02 15:44">2016-02-02 15:44</span> </div> </div> <div id="31438729" class="answer " itemscope itemtype="http://schema.org/Answer" itemprop="suggestedAnswer"> <div class="a-body"> <div class="a-text" itemprop="text"> <p>Я немного поэкспериментировал и определил причину до такой степени, поэтому в ожидании реального ответа, который меня заинтересует, вот хак, чтобы помочь понять проблему</p><pre><code>$.get('/',function(d){ // replace the `HTML` tags with `NOTHTML` tags // and the `BODY` tags with `NOTBODY` tags d = d.replace(/(<\/?)html( .+?)?>/gi,'$1NOTHTML$2>',d) d = d.replace(/(<\/?)body( .+?)?>/gi,'$1NOTBODY$2>',d) // select the `notbody` tag and log for testing console.log($(d).find('notbody').html()) }) </code></pre><h2>Редактировать: дальнейшие эксперименты</h2><p>Кажется, это возможно, если вы загружаете контент в iframe, тогда вы можете получить доступ к содержимому фрейма через некоторую иерархию объектов dom...</p><pre><code>// get a page using AJAX $.get('/',function(d){ // create a temporary `iframe`, make it hidden, and attach to the DOM var frame = $('<iframe id="frame" src="/" style="display: none;"></iframe>').appendTo('body') // check that the frame has loaded content $(frame).load(function(){ // grab the HTML from the body, using the raw DOM node (frame[0]) // and more specifically, it's `contentDocument` property var html = $('body',frame[0].contentDocument).html() // check the HTML console.log(html) // remove the temporary iframe $("#frame").remove() }) }) </code></pre><h2>Редактировать: больше исследований</h2><p>Кажется, что contentDocument - это совместимый со стандартами способ получить <code>window.document</code> элемент iFrame, но, конечно, IE на самом деле не заботится о стандартах, так что вот как получить ссылку на iFrame <code>window.document.body</code> объект кросс-платформенным способом...</p><pre><code>var iframeDoc = iframe.contentDocument || iframe.contentWindow.document; var iframeBody = iframeDoc.body; // or for extra caution, to support even more obsolete browsers // var iframeBody = iframeDoc.getElementsByTagName("body")[0] </code></pre><p>Смотрите: <a href="/questions/21911349/contentdocument-dlya-frejma" target="_blank">contentDocument для iframe</a></p> </div> <div class="a-info"> <div class="row"> <div class="col-sm-2"> <a class="like-button" title="Чтобы оценить ответ необходимо войти под своим логином." > <div class="btn btn-my btn-block" style="background: #bdc3c7 "> <span itemprop="upvoteCount">6</span> <i class="far fa-thumbs-up"></i> </div> </a> </div> </div> <div class="row"> <div class="col-sm-4"> <a class="a-source" href="https://stackoverflow.com/questions/14423257/find-body-tag-in-an-ajax-html-response/14423412#14423412" target="_blank">Источник</a> <a class="a-share" href="https://stackru.com/questions/31438706/najti-teg-body-v-otvete-ajax-html/31438729#31438729" itemprop="url">Поделиться</a> </div> <div class="col-sm-8 text-right author" itemprop="author" itemscope="" itemtype="http://schema.org/Person"> <span itemprop="name"> <a href="https://stackoverflow.com/users/665261/user665261" class="q-user" rel="noopener" target="_blank">user665261</a> </span> <span class="q-date" title="2013-01-20 10:00"> 20 янв '13 в 10:00</span> <span class="hidden" itemprop="dateCreated" datetime="2013-01-20 10:00">2013-01-20 10:00</span> </div> </div> </div> <span class="hidden" itemprop="dateCreated" datetime="2013-01-20 10:00">2013-01-20 10:00</span> </div> </div> <div id="31438736" class="answer " itemscope itemtype="http://schema.org/Answer" itemprop="suggestedAnswer"> <div class="a-body"> <div class="a-text" itemprop="text"> <p>Я выяснил что-то чудесное (я думаю!)</p><p>Получил ваш HTML в виде строки?</p><pre><code>var results = //probably an ajax response </code></pre><p>Вот объект jquery, который будет работать точно так же, как элементы, в настоящее время прикрепленные к DOM:</p><pre><code>var superConvenient = $($.parseXML(response)).children('html'); </code></pre><p>Ничего не будет снято с <code>superConvenient</code>! Вы можете делать такие вещи, как <code>superConvenient.find('body')</code> или даже</p><pre><code>superConvenient.find('head > script'); </code></pre><p><code>superConvenient</code> работает точно так же, как элементы jquery, к которым все привыкли!!!!</p><h1>НОТА</h1><p>В этом случае строка <code>results</code> должен быть <em>действительным XML,</em> потому что он подается в JQuery <code>parseXML</code> метод. Общей чертой ответа HTML может быть <code><!DOCTYPE></code> тег, который сделает документ недействительным в этом смысле. <code><!DOCTYPE></code> теги, возможно, должны быть удалены перед использованием этого подхода! Также следите за такими функциями, как <code><!--[if IE 8]>...<![endif]--></code>теги без закрывающих тегов, например:</p><pre><code><ul> <li>content... <li>content... <li>content... </ul> </code></pre><p>... и любые другие функции HTML, которые будут снисходительно интерпретироваться браузерами, но приводят к сбою синтаксического анализатора XML.</p> </div> <div class="a-info"> <div class="row"> <div class="col-sm-2"> <a class="like-button" title="Чтобы оценить ответ необходимо войти под своим логином." > <div class="btn btn-my btn-block" style="background: #bdc3c7 "> <span itemprop="upvoteCount">5</span> <i class="far fa-thumbs-up"></i> </div> </a> </div> </div> <div class="row"> <div class="col-sm-4"> <a class="a-source" href="https://stackoverflow.com/questions/14423257/find-body-tag-in-an-ajax-html-response/23876751#23876751" target="_blank">Источник</a> <a class="a-share" href="https://stackru.com/questions/31438706/najti-teg-body-v-otvete-ajax-html/31438736#31438736" itemprop="url">Поделиться</a> </div> <div class="col-sm-8 text-right author" itemprop="author" itemscope="" itemtype="http://schema.org/Person"> <span itemprop="name"> <a href="https://stackoverflow.com/users/830905/user830905" class="q-user" rel="noopener" target="_blank">user830905</a> </span> <span class="q-date" title="2014-05-26 19:41"> 26 май '14 в 19:41</span> <span class="hidden" itemprop="dateCreated" datetime="2014-05-26 19:41">2014-05-26 19:41</span> </div> </div> </div> <span class="hidden" itemprop="dateCreated" datetime="2014-05-26 19:41">2014-05-26 19:41</span> </div> </div> <div id="55384727" class="answer " itemscope itemtype="http://schema.org/Answer" itemprop="suggestedAnswer"> <div class="a-body"> <div class="a-text" itemprop="text"> <p>Решение Regex, которое сработало для меня:</p><pre><code>var head = res.match(/<head.*?>.*?<\/head.*?>/s); var body = res.match(/<body.*?>.*?<\/body.*?>/s); </code></pre><p>Подробное объяснение: <a href="https://regex101.com/r/kFkNeI/1" rel="noopener nofollow noreferrer" target="_blank">https://regex101.com/r/kFkNeI/1</a></p> </div> <div class="a-info"> <div class="row"> <div class="col-sm-2"> <a class="like-button" title="Чтобы оценить ответ необходимо войти под своим логином." > <div class="btn btn-my btn-block" style="background: #bdc3c7 "> <span itemprop="upvoteCount">2</span> <i class="far fa-thumbs-up"></i> </div> </a> </div> </div> <div class="row"> <div class="col-sm-4"> <a class="a-source" href="https://stackoverflow.com/questions/14423257/find-body-tag-in-an-ajax-html-response/57449783#57449783" target="_blank">Источник</a> <a class="a-share" href="https://stackru.com/questions/31438706/najti-teg-body-v-otvete-ajax-html/55384727#55384727" itemprop="url">Поделиться</a> </div> <div class="col-sm-8 text-right author" itemprop="author" itemscope="" itemtype="http://schema.org/Person"> <span itemprop="name"> <a href="https://stackoverflow.com/users/4563136/user4563136" class="q-user" rel="noopener" target="_blank">user4563136</a> </span> <span class="q-date" title="2019-08-11 15:00"> 11 авг '19 в 15:00</span> <span class="hidden" itemprop="dateCreated" datetime="2019-08-11 15:00">2019-08-11 15:00</span> </div> </div> </div> <span class="hidden" itemprop="dateCreated" datetime="2019-08-11 15:00">2019-08-11 15:00</span> </div> </div> <div class="text-center"> </div> <div class="text-center"> </div> <div class="another-questions"> <div class="row"> <div class="col-md-12 q-tags"> <b>Другие вопросы по тегам</b> <a href="/questions/tagged/javascript" class="tag-block-link" rel="tag" title="показать вопросы с тегом 'javascript'">javascript</a> <a href="/questions/tagged/jquery" class="tag-block-link" rel="tag" title="показать вопросы с тегом 'jquery'">jquery</a> <a href="/questions/tagged/ajax" class="tag-block-link" rel="tag" title="показать вопросы с тегом 'ajax'">ajax</a> <a href="/questions/tagged/document-body" class="tag-block-link" rel="tag" title="показать вопросы с тегом 'document-body'">document-body</a> </div> </div> </div> </div> </div> <div class="col-lg-3 AD"> <div id="allFlyout3-0" style="position: sticky; top: 0;"> </div> </div> </div> </div> </section> </main> <div class="padding"></div> </div> <footer> <div class="container"> <div class="row"> <div class="col-sm-6"> <a href="/"> <img src="/static/img/logo.png" alt="stackru.com - Поиск вопросов и ответов по программированию" /> </a> </div> <div class="col-sm-6 text-right"> <span class="pull-right"><a href="mailto:info@stackru.com">info@stackru.com</a></span> <br /> <span class="license pull-left">licensed under <a href="https://creativecommons.org/licenses/by-sa/3.0/" rel="nofollow license" target="_blank">cc by-sa 3.0</a> with attribution</span> </div> </div> </div> </footer> <!-- Yandex.Metrika counter --> <script type="text/javascript" > (function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)}; m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)}) (window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym"); ym(53936023, "init", { clickmap:true, trackLinks:true, accurateTrackBounce:true, webvisor:true }); </script> <noscript><div><img src="https://mc.yandex.ru/watch/53936023" style="position:absolute; left:-9999px;" alt="" /></div></noscript> <!-- /Yandex.Metrika counter --> <!-- Global site tag (gtag.js) - Google Analytics --> <script async src="https://www.googletagmanager.com/gtag/js?id=UA-141489240-1"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'UA-141489240-1'); </script> </body> </html>