使用 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
)
对于获取,组件不要添加<body>
或<HTML>
标签<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 页面上