列表2.19 添加用于解析响应和查找标题的函数: ./app/renderer.js
const parseResponse = (text) => { return parser.parseFromString(text, 'text/html'); //从URL获取HTML字符串并将其解析为DOM树。 } const findTitle = (nodes) =>{ return nodes.querySelector('title').innerText; //遍历DOM树以找到标题节点。 }
现在我们可以将这两个步骤添加到我们的处理链中。
列表2.20 解析响应并在获取页面时查找标题: ./app/renderer.js
fetch(url) .then(response => response.text()) .then(parseResponse) .then(findTitle);
此时,app/renderer.js中的代码看起来是这样的。
const parser = new DOMParser(); const linksSection = document.querySelector('.links'); const errorMessage = document.querySelector('.error-message'); const newLinkForm = document.querySelector('.new-link-form'); const newLinkUrl = document.querySelector('.new-link-url'); const newLinkSubmit = document.querySelector('.new-link-submit'); const clearStorageButton = document.querySelector('.clear-storage'); newLinkUrl.addEventListener('keyup', () => { newLinkSubmit.disabled = !newLinkUrl.validity.valid; }); newLinkForm.addEventListener('submit', (event) => { event.preventDefault(); const url = newLinkUrl.value; fetch(url) .then(response => response.text()) .then(parseResponse) .then(findTitle) }); const clearForm = () => { newLinkUrl.value = null; } const parseResponse = (text) => { return parser.parseFromString(text, 'text/html'); } const findTitle = (nodes) => { return nodes.querySelector('title').innerText; }使用web storage APIs存储响应
localStorage是一个简单的键/值存储,内置在浏览器中并持久保存之间的会话。您可以在任意键下存储简单的数据类型,如字符串和数字。让我们设置另一个帮助函数,它将从标题和URL生成一个简单的对象,使用内置的JSON库将其转换为字符串,然后使用URL作为键存储它。
图2.22 创建一个函数来在本地存储中保存链接: ./app/renderer.js
const storeLink = (title, url) => { localStorage.setItem(url, JSON.stringify({ title: title, url: url })); };
我们的新storeLink函数需要标题和URL来完成它的工作,但是前面的处理只返回标题。我们使用一个箭头函数将对storeLink的调用封装在一个匿名函数中,该匿名函数可以访问作用域中的url变量。如果成功,我们也清除表单。
图2.23 存储链接并在获取远程资源时清除表单: ./app/renderer.js
fetch(url) .then(response => response.text()) .then(parseResponse) | .then(findTitle) |将标题和URL存储到localStorage .then(title => storeLink(title, url)) <---+ .then(clearForm);显示请求结果
存储链接是不够的。我们还希望将它们显示给用户。这意味着我们需要创建功能来遍历存储的所有链接,将它们转换为DOM节点,然后将它们添加到页面中。
让我们从从localStorage获取所有链接的能力开始。如果你还记得,localStorage是一个键/值存储。我们可以使用对象。获取对象的所有键。我们必须为自己提供另一个帮助函数来将所有链接从localStorage中取出。这没什么大不了的,因为我们需要将它们从字符串转换回实际对象。让我们定义一个getLinks函数。
图2.24 创建用于从本地存储中获取链接的函数: ./app/renderer.js
const getLinks = () => { | |获取当前存储在localStorage中的所有键的数组 return Object.keys(localStorage) <---+ .map(key => JSON.parse(localStorage.getItem(key))); <----+ } |对于每个键,获取其值 |并将其从JSON解析为JavaScript对象
接下来,我们将这些简单的对象转换成标记,以便稍后将它们添加到DOM中。我们创建了一个简单的convertToElement 帮助函数,它也可以处理这个问题。需要指出的是,我们的convertToElement函数有点幼稚,并且不尝试清除用户输入。理论上,您的应用程序很容易受到脚本注入攻击。这有点超出了本章的范围,所以我们只做了最低限度的渲染这些链接到页面上。我将把它作为练习留给读者来确保这个特性的安全性。