我的HTML有什么问题,jQuery没有解析它?

时间:2017-05-10 16:48:29

标签: jquery ajax html-parsing

我一直在尝试获取HTML文件并将其作为jQuery对象分配给变量。无济于事。我不确定Stack Snippets是否允许GET请求,所以这里也是JSFiddle link

    var html = '<!DOCTYPE html><html lang="en"><head><title>Template</title></head><body itemscope itemtype="http://schema.org/WebPage"><main><header itemscope itemtype="http://schema.org/Country" itemprop="about"><h1 itemprop="name">Dummy heading</h1><p><span class="capital" title="Capital" itemprop="containsPlace"></span><span title="Dummy title" itemprop="additionalProperty" itemscope itemtype="http://schema.org/PropertyValue"><meta itemprop="name" content="Member of the EU since"><span itemprop="value" class="member-since">Dummy year</span></span></p></header><div itemprop="mainEntity" itemscope itemtype="http://schema.org/ItemList"><meta itemprop="description" content=""><article class="recipe loading" itemprop="itemListElement" itemscope itemtype="http://schema.org/Recipe"><meta itemprop="position" content=""><aside class="media"><div class="img-gallery" itemscope itemtype="http://schema.org/ImageGallery"></div><div itemscope itemtype="http://schema.org/VideoObject" class="youtube"><a itemprop="contentUrl" href="#" title=""><meta itemprop="name" content=""><meta itemprop="uploadDate" content=""><meta itemprop="description" content=""><img itemprop="thumbnailUrl" src="#" alt=""></a><div class="youtube-player"></div></div></aside><div class="text"><div class="wiki-text"><h1 itemprop="name">Dummy heading</h1><p itemprop="description"></p><p class="read-more">For more information about <span class="recipe-name"></span>, read the <a href="#" title="" itemprop="sameAs">Wiki</a>.</p></div><div class="rating" itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating">Rated <span itemprop="ratingValue">3.5</span>/5 based on <span itemprop="reviewCount">11</span> customer reviews</div><div class="cooking"><h2>Bake it yourself!</h2><div><meta itemprop="cookTime" content=""><span>Bake time: <span class="bake-time"></span></span></div><div class="ingredients-wrapper"><h3>Ingredients <small>for <span itemprop="recipeYield"></span></small></h3><div class="ingredients"><h4>Dummy heading</h4><ul></ul></div></div><div class="how-to"><h3>Steps</h3><ol></ol></div></div></div></article></div></main></body></html>';
    
    $.ajax({
      type: 'post',
      url: "/echo/html/",
      dataType: "html",
      data: {
        html: html,
        delay: 1
      }
    }).done(function(data) {
      // string
    	console.log(data);
      // array
      console.log($(data));
      // array
      console.log($.parseHTML(data));
      // array
      console.log($($.parseHTML(data)));
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

HTML有效。然而,我不能把它放在一个对象中。正如预期的那样,返回的数据是一个字符串。但是当我尝试使用$.parseHTML()将该字符串解析为HTML或将其放入jQuery选择器$()或甚至尝试两者时,我总是得到相同的结果:包含title和main元素的数组。

所以某种方式jQuery如何仍然解析它并在头部和主体中的一个元素中创建元素的数组。但为什么?我该如何解决这个问题,并将其转换为jQuery对象?我只对身体的内容感兴趣。

a similar question,但是接受的解决方案没有帮助,因为它进入JSFiddle,我也在XAMPP本地遇到这个问题。

4 个答案:

答案 0 :(得分:2)

>>> import decimal
>>> x = 10 ** 1000
>>> d = decimal.Decimal(x)
>>> format(d, '.6e')
'1.000000e+1000' 

......只是有效。所以我已经预料到了:

document.querySelector("body").innerHTML = + 
  '<object type="text/html" data="'+html+'" ></object>';

也只是工作,但是当我真正将它添加到DOM时,我猜测会发生一些魔法。它解析它,为它构建CSSOM和DOM并加载所有依赖项,基本上是你期望浏览器使用let parsedHtml = $('<object />', { type:'text/html', data:html }).html() 资源。

所以这是一种方法:

  1. 创建一个虚拟占位符
  2. .html放在里面,
  3. 将虚拟添加到DOM,
  4. 获取<object> .contents()(其中<object>事件),
  5. 并删除假人。
  6. onload

    注意Chrome已足够聪明,可以检测父级let html = '// your valid html...', dummyDiv = $('<div />',{ html: '<object type="text/html" data="'+html+'" ></object>', style:"height:0;overflow:hidden;" }); $('html').append(dummyDiv); console.log(dummyDiv.find('object').contents()); 无法加载 display:none 。这就是我使用<object>的原因。你会注意到这个元素的内容没有jQuery对象的典型结构,因为它是一个文档。你会在

    中找到果汁
    height:0;overflow:hidden;

    当html字符串已经存在于变量中时,它会立即加载,但实际上您需要在dummyDiv.find('object').contents()[1].innerHTML 上放置一个onload侦听器,并且只运行 4。 5。,当侦听器触发时。

答案 1 :(得分:1)

jQuery.ajax() processData选项设为false。使用DOMParser()将字符串解析为html document; XMLSerizlizer()获得DOCTYPE声明; document.write()要写DOCTYPE并将document .documentElement.outerHTML解析为当前或其他html document

  

processData (默认:true

     

类型:布尔值

     

默认情况下,数据作为对象传入data选项   (技术上,除了字符串之外的任何东西)将被处理和   转换为查询字符串,适合默认的内容类型   &#34;应用程序/ X WWW的窗体-urlencoded&#34 ;.如果你想发送一个   DOMDocument或其他未处理的数据将此选项设置为false

  

我不确定Stack Snippets是否允许GET请求

是。通过在GETurl或{{1}设置data URIBlob URL$.ajax()资源的表示,可以回复XMLHttpRequest()请求},请参阅Does Stack Overflow have an “echo page” to test AJAX requests, inside a code snippet?

&#13;
&#13;
fetch()
&#13;
var html = `<!DOCTYPE html>
<html lang="en">

<head>
  <title>Template</title>
</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <main>
    <header itemscope itemtype="http://schema.org/Country" itemprop="about">
      <h1 itemprop="name">Dummy heading</h1>
      <p><span class="capital" title="Capital" itemprop="containsPlace"></span><span title="Dummy title" itemprop="additionalProperty" itemscope itemtype="http://schema.org/PropertyValue"><meta itemprop="name" content="Member of the EU since"><span itemprop="value" class="member-since">Dummy year</span></span>
      </p>
    </header>
    <div itemprop="mainEntity" itemscope itemtype="http://schema.org/ItemList">
      <meta itemprop="description" content="">
      <article class="recipe loading" itemprop="itemListElement" itemscope itemtype="http://schema.org/Recipe">
        <meta itemprop="position" content="">
        <aside class="media">
          <div class="img-gallery" itemscope itemtype="http://schema.org/ImageGallery"></div>
          <div itemscope itemtype="http://schema.org/VideoObject" class="youtube">
            <a itemprop="contentUrl" href="#" title="">
              <meta itemprop="name" content="">
              <meta itemprop="uploadDate" content="">
              <meta itemprop="description" content=""><img itemprop="thumbnailUrl" src="#" alt=""></a>
            <div class="youtube-player"></div>
          </div>
        </aside>
        <div class="text">
          <div class="wiki-text">
            <h1 itemprop="name">Dummy heading</h1>
            <p itemprop="description"></p>
            <p class="read-more">For more information about <span class="recipe-name"></span>, read the <a href="#" title="" itemprop="sameAs">Wiki</a>.</p>
          </div>
          <div class="rating" itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating">Rated <span itemprop="ratingValue">3.5</span>/5 based on <span itemprop="reviewCount">11</span> customer reviews</div>
          <div class="cooking">
            <h2>Bake it yourself!</h2>
            <div>
              <meta itemprop="cookTime" content=""><span>Bake time: <span class="bake-time"></span></span>
            </div>
            <div class="ingredients-wrapper">
              <h3>Ingredients <small>for <span itemprop="recipeYield"></span></small></h3>
              <div class="ingredients">
                <h4>Dummy heading</h4>
                <ul></ul>
              </div>
            </div>
            <div class="how-to">
              <h3>Steps</h3>
              <ol></ol>
            </div>
          </div>
        </div>
      </article>
    </div>
  </main>
</body>
</html>`;


$.ajax({
    type: "GET",
    url: "data:text/html," + html,
    processData: false
  })
  .then(function(data) {
    // string
    console.log(data);
    var parser = new DOMParser();
    // document
    var d = parser.parseFromString(data, "text/html");
    // `document`, `document` as jQuery object
    console.log(d, $(d));
    // get elements having `itemscope` attribute
    console.log($(d).find("[itemscope]"));
    // do stuff
    var dt = new XMLSerializer().serializeToString(d.doctype);
    document.write(dt, d.documentElement.outerHTML);
  })
  .fail(function(jqxhr, textStatus, errorThrown) {
    console.log(errorThrown);
  });
  
  
&#13;
&#13;
&#13;

还可以使用<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>元素将html document导入当前document<link>属性设置为rel,相关How to append a whole html file with jquery

答案 2 :(得分:0)

Problem is you are trying to access direct html but actually its a string.

So you have to render html to access data.

For that store response data into any html element and access through it.

I changed your jsfiddle so you can see.

答案 3 :(得分:0)

  

我总是得到相同的结果:一个包含title和main元素的数组。

究竟是什么问题?

  

jQuery仍然会解析它并在头部创建一个元素数组,并在正文中创建一个元素。但为什么呢?

你有什么期待?

这似乎是parseHtml的行为。

这是另一个例子:

$.parseHTML("<div>Hello<span>World</span></div>")

它返回一个包含一个元素的数组:div

如果你看docs for parseHTML它说:

  

将字符串解析为DOM节点数组。

所以它似乎完全按照预期行事。

  

我只对身体的内容感兴趣。

正文的内容是main,正如您所指出的那样是第二个元素。

你想用它做什么?

您可以将它传递给jQuery构造函数,将其包装在jQuery对象中。

var html = '<!DOCTYPE html><html lang="en"><head><title>Template</title></head><body itemscope itemtype="http://schema.org/WebPage"><main><header itemscope itemtype="http://schema.org/Country" itemprop="about"><h1 itemprop="name">Dummy heading</h1><p><span class="capital" title="Capital" itemprop="containsPlace"></span><span title="Dummy title" itemprop="additionalProperty" itemscope itemtype="http://schema.org/PropertyValue"><meta itemprop="name" content="Member of the EU since"><span itemprop="value" class="member-since">Dummy year</span></span></p></header><div itemprop="mainEntity" itemscope itemtype="http://schema.org/ItemList"><meta itemprop="description" content=""><article class="recipe loading" itemprop="itemListElement" itemscope itemtype="http://schema.org/Recipe"><meta itemprop="position" content=""><aside class="media"><div class="img-gallery" itemscope itemtype="http://schema.org/ImageGallery"></div><div itemscope itemtype="http://schema.org/VideoObject" class="youtube"><a itemprop="contentUrl" href="#" title=""><meta itemprop="name" content=""><meta itemprop="uploadDate" content=""><meta itemprop="description" content=""><img itemprop="thumbnailUrl" src="#" alt=""></a><div class="youtube-player"></div></div></aside><div class="text"><div class="wiki-text"><h1 itemprop="name">Dummy heading</h1><p itemprop="description"></p><p class="read-more">For more information about <span class="recipe-name"></span>, read the <a href="#" title="" itemprop="sameAs">Wiki</a>.</p></div><div class="rating" itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating">Rated <span itemprop="ratingValue">3.5</span>/5 based on <span itemprop="reviewCount">11</span> customer reviews</div><div class="cooking"><h2>Bake it yourself!</h2><div><meta itemprop="cookTime" content=""><span>Bake time: <span class="bake-time"></span></span></div><div class="ingredients-wrapper"><h3>Ingredients <small>for <span itemprop="recipeYield"></span></small></h3><div class="ingredients"><h4>Dummy heading</h4><ul></ul></div></div><div class="how-to"><h3>Steps</h3><ol></ol></div></div></div></article></div></main></body></html>';

var parsed = $.parseHTML(html)
var main = parsed[1]
var $main = $(main)
// $main is a jQuery object
console.log("h4 content:", $main.find('h4').text())