使用 fetch() 返回 HTML

Posted

技术标签:

【中文标题】使用 fetch() 返回 HTML【英文标题】:Returning HTML With fetch() 【发布时间】:2016-08-06 12:26:34 【问题描述】:

我正在尝试获取一个文件并返回它的 html。然而事情并没有我想象的那么简单。

    fetch('/path/to/file')
    .then(function (response) 
      return response.body;
    )
    .then(function (body) 
      console.log(body);
    );

这将返回一个名为 ReadableByteStream 的对象。如何使用它来获取 HTML 文件内容?

如果我将/path/to/file 的内容更改为 JSON 字符串,并将上面的内容更改为:

    fetch('/path/to/file')
    .then(function (response) 
      return response.json();
    )
    .then(function (json) 
      console.log(json);
    );

... 它正确返回 JSON。如何获取 HTML?

【问题讨论】:

这引起了人们的关注:你打算用那个 HTML 做什么?因为我希望它不是“将其注入我的活动文档中”。而是以 JSON 形式请求数据,然后围绕该数据在客户端构建 DOM,以便您知道用户不会加载可能被黑客入侵和超级不安全的盲 HTML。 @Mike'Pomax'Kamermans 您假设 HTML 来自用户。我返回服务器端生成的 HTML 以利用使用强类型服务器语言创建的强类型视图。 你信任你的服务器吗?我当然不信任我的,我什至不拥有它运行的硬件。我可以全心全意地推荐使用morphdom,而不是要求HTML,而不是:让您的服务器生成HTML,然后生成一个发送给您的客户端的diff,并让他们将该差异应用于活动再次使用 morphdom 的 DOM。更小的有效载荷,因此响应速度更快,也更安全。 @Mike'Pomax'Kamermans 因为 JS 可以在控制台中运行,所以用户不能在活动文档中注入任何东西吗? 没有开启理智的 CSP,没有。他们可以添加它,但浏览器会拒绝运行它,因为它违反了服务器的script-src CSP 规则。 【参考方案1】:

您可以使用 fetch 下载 html,然后使用 DomParser API 对其进行解析。

fetch('somePage.html')
    .then(function(response) 
        // When the page is loaded convert it to text
        return response.text()
    )
    .then(function(html) 
        // Initialize the DOM parser
        var parser = new DOMParser();

        // Parse the text
        var doc = parser.parseFromString(html, "text/html");

        // You can now even select part of that html as you would in the regular DOM 
        // Example:
        // var docArticle = doc.querySelector('article').innerHTML;

        console.log(doc);
    )
    .catch(function(err)   
        console.log('Failed to fetch page: ', err);  
    );

【讨论】:

不知道,我一直在使用innerHTML 很高兴答案正是我想要的,即使问题没有提到写入 DOM。同样相关:api.jquery.com/load @caffeinum - 谢谢!当您获取外部 html 页面时,它将是纯文本格式,您无法对此做任何有意义的事情。恕我直言,下一步自然是对该文档做一些事情,为了做到这一点,我们必须将该文本解析为 DOM。此时我们可以选择和操作该文档。我不想故意提到 jQuery,因为未来在 vanilla JS 中。我们都应该过渡到那个,如果我们还没有的话。 所以附加到这个文件的脚本会运行??【参考方案2】:

您需要使用.text() 方法,而不是.json()。这会将字节流转换为纯文本,浏览器可以将其解析为 HTML。

【讨论】:

【参考方案3】:

您可以使用.text() 返回响应, 然后根据需要在文档中呈现页面。

function fetchHtml() 
  fetch('./file.html')
  .then((response) => 
    return response.text();
  )
  .then((html) => 
    document.body.innerHTML = html     
  );

【讨论】:

【参考方案4】:

将 Promise Chaining 与 .then() 结合使用是一种较旧的编码获取和响应的方法。更现代的方法是使用async functions and await,如下所示:

async function fetchMyDocument()       
  try 
    let response = await fetch('/path/to/file.html'); // Gets a promise
    document.body.innerHTML = await response.text(); // Replaces body with response
   catch (err) 
    console.log('Fetch error:' + err); // Error handling
  

关于问题的直接答案,(与其他所有答案一样).text() 用于响应而不是 .json()

【讨论】:

【参考方案5】:

应该是:

fetch('/path/to/file').then(function(response) 
    return response.text();
).then(function(string) 
    console.log(string);
).catch(function(err)   
    console.log('Fetch Error', err);  
);

【讨论】:

【参考方案6】: 1-调用函数fetch并添加页面路径。 2-然后通过函数.text()将获取数据转换为文本。 3- 然后append 页面组件到您的父容器。

       async function getAbout() 


    await fetch('./component/about.html').then(res => res.text()).then(data => 
    page_2.innerHTML = data;

     ).then(() => 
       
         // after fetch write js code here  
     )

对于获取,组件不要添加&lt;body&gt;&lt;HTML&gt;标签<div>或其他标签。

为了获得更好的性能使用 async-await!。

【讨论】:

【参考方案7】:

使用这个:

var fetchAndParse = async (url) =>  let div = document.createElement("div"); div.innerHTML = await (await fetch(url)).text(); return div 

今天我想知道所有开源许可证的长度。我最终在https://opensource.org/licenses/alphabetical 上运行了这样的代码(删除.slice(0, 3) 以将其映射到所有链接):

var $$ = (x) => ([...document.querySelectorAll(x)])
var fetchAndParse = async (url) =>  let div = document.createElement("div"); div.innerHTML = await (await fetch(url)).text(); return div 
var waitTimeout = async (duration) =>  return new Promise((accept) => setTimeout(accept, duration)) 
var licenseArray = await Promise.all($$("#main a[href]").slice(0, 3).map(async (anchor, k) => 
  let text = await fetchAndParse(anchor.href).then(div => div.querySelector("#main").textContent.replace(/\s+/g, ' ').trim()).catch(error =>  console.error(anchor.href, error); return '' )
  return [anchor.href.replace(/^.*\//, ''), anchor.textContent.length, text.length, anchor.textContent,  href: anchor.href, text ]
))

【讨论】:

以上是关于使用 fetch() 返回 HTML的主要内容,如果未能解决你的问题,请参考以下文章

在 JavaScript 中使用 fetch() 时,如何将返回对象的详细信息呈现到 html 页面上

为啥 fetch 返回 status = 0 的响应?

Fetch -API 返回 HTML 而不是 JSON

将 PHP 异常返回到 javascript FETCH API

使用 fetch 时如何从 MVC 控制器返回错误

Node-fetch 不提供正文中页面的所有 HTML