我正在努力从新闻网站上抓文章 . 我已经成功地删除了文章,数据已成功到达前端 . (它正确的console.log) . 我的问题是我无法使用按钮将数据呈现到页面上 - 数据仅在我刷新时填充页面 .
我知道这个问题与Handlebars有关,因为如果我尝试使用jQuery渲染页面,它就可以了 .
我相信这与我的路线有关 . 我通过/ articles路由将数据发送到页面,但正如您所看到的,我并没有专门使用res.render或res.redirect . 我想这就是为什么它不起作用?但是,我不知道如何解决它 . 我对路线和回调有点不稳定 . 我是编码的新手,但我向你保证,我已经研究并尝试了许多修复无济于事 . 任何帮助或指导表示赞赏 . 谢谢 .
app.get("/", function(req, res) {
db.Article
.find({})
.then(function(dbArticle) {
// res.render("index");
res.render("index", { articles : dbArticle });
});
});
app.get("/scrape", function(req, res) {
axios.get("https://www.nytimes.com/section/technology?
action=click&pgtype=Homepage®ion=TopBar&module=HPMini
Nav&contentCollection=Tech&WT.nav=page")
.then(function(response) {
var $ = cheerio.load(response.data);
$("a.story-link").each(function(i, element) {
var results = {};
results.link = $(this).attr("href");
// console.log("This is my link " + results.link)
results.blurb = $(this).children().find(".summary").text();
// console.log("This is my blurb " + results.blurb)
results.headline = $(this).children().find(".headline").text();
// console.log("This is my headline " + results.headline)
db.Article
.create(results)
.then(function(dbArticle) {
res.json(dbArticle);
// res.end();
// console.log("YES", dbArticle);
})
.catch(function(err) {
res.json(err);
})
})
})
})
app.get("/articles", function(req, res) {
db.Article
.find({})
.then(function(dbArticle) {
res.json(dbArticle);
// console.log(dbArticle, "scraped")
})
.catch(function(err) {
res.json(err);
});
});`
1 回答
在某个地方,你有一个概念上的脱节 . 我不知道到底在哪里,我将试图涵盖一些基础知识,希望我可以填补相关的差距 .
我们假设您的Express服务器运行在
localhost:3000
. 它并没有localhost
,如果代码在世界各地的计算机上运行,一切都会有相同的效果 . 关键是浏览器无法看到您的代码,它具有HTML,CSS,JavaScript等的先天知识,但对您的应用程序一无所知 .当您在浏览器地址栏中键入URL
http://localhost:3000/
时,它会在运行localhost:3000
的服务器上发出HTTPGET
路径GET
请求 . 请求只是发送的字节序列'over the wire'(当我说'wire'认为网络电缆时,即使没有't actually a physical network cable involved). Using your browser's开发工具看看网络部分并查看此特定请求 . 点击它并查看请求细节 .浏览器完全不知道服务器中发生了什么 . 请记住,就浏览器而言,这台服务器“遍布全球” .
当此请求到达您的服务器时,它将'll wend it'指向您在
app.get('/', ...
注册的路线 . 对res.render
的调用将运行Handlebars模板并生成一个HTML标记字符串 . 然后将此字符串转换为字节,并将这些字节作为响应正文发送回'over the wire' . 响应还有一些 Headers 来描述's in the body but ultimately it'只是序列中发送的很多字节 .这个响应是回到浏览器的 . 它不知道它是如何生成的 . 就浏览器而言,它可以很容易地从静态文件中提供 . 重要的是要理解它与相应的标记是截然不同的(虽然密切相关) . 关于术语的简短说明,我们称之为标记中的
tag
成为DOM中的一个element
节点 . 然后,浏览器获取DOM节点树并使用它们生成页面图像,这是实际在浏览器视口中向用户显示的图像 .为什么我一直在谈论通过网络发送'字节'?不是一切都只是字节?嗯,是的,不 . 如果你有一个像数组或对象这样的数据结构,你不能只是通过网络发送它 . 它可能使用计算机内存中的字节来表示,但要将其作为HTTP请求/响应的一部分发送,需要将其转换为一种格式,将其表示为一个接一个的线性字节序列 . 此过程通常称为序列化 . HTML标记字符串是HTML DOM节点的序列化表示,就像JSON通常用作序列化JavaScript数据结构(如对象和数组)的方式一样 .
所以,回到我们的
/
请求,如果您查看浏览器的网络部分's dev tools you'将能够看到请求和响应 . 它以格式良好的方式呈现它,因此您不必知道您使用Handlebars来创建HTML标记 .当然,标记可以包含其他资源的URL,例如图像,CSS,JavaScript等 . 当浏览器将标记解析为DOM节点时,它会遇到这些其他URL,并在需要时为每个URL发出单独的HTTP请求 . 这些请求中的每一个都与原始
/
请求的行为大致相同,并且浏览器再次不知道服务器如何生成响应:它可能返回一个内容静态文件或它可以在运行中生成整个响应 .现在我们来讨论更新页面以响应用户交互的主题 .
也许最容易理解的互动是点击链接,即像
<a href="/other-url">click</a>
这样的锚标签 . 这只会更新浏览器地址栏中的URL并丢弃上一页 .HTML表单类似,但它可以执行各种其他技巧,例如
POST
请求 . 表单是使用<form>
元素构建的(也许更准确地说我应该说form
元素,没有<
和>
,但我认为<form>
更容易理解,只要我们_1149084_与锚链接非常相似 . 浏览器URL得到更新并且是新的页面被加载到它's place. (I'这里不会覆盖它,但是有提交表单的方法,以便当前页面不会改变) .这两种方法都会丢弃页面并从服务器上重新加载它 . 多年来,这就是动态网站的构建方式 . 然后AJAX出现了 .
使用AJAX,您可以在JavaScript中执行HTTP请求,而无需更改当前页面位置 . 浏览器并没有真正尝试理解从AJAX请求返回的响应,它只是进行了一些基本的解析,然后将其交给您注册的任何回调 .
这让我们回到原来的例子 . 您有一个AJAX请求呼叫服务器并撤回一些JSON数据 . 然后使用jQuery使用该JSON相应地更新页面的DOM节点 . 这是一个非常好的方法,但让我们谈谈一些替代方案 .
目标是更新页面以反映新数据,就像我们完整刷新页面一样 . 为此,我们需要使用由Handlebars生成的标记中的jQuery构建完全相同的DOM节点结构 . 这显然违反了DRY原则,因为我们在两个地方重复了相同的结构 .
删除此重复的一种方法是始终使用AJAX加载页面的该部分 . 使用Handlebars(在服务器上)初始呈现页面将使页面的该部分留空,然后一旦页面加载,一些客户端JavaScript将用于启动AJAX请求 . 这可能会略微延迟页面的初始加载时间,也可能导致SEO出现问题,但对于很多SPA而言,这些并不是很重要的问题,因此这就是使用的方法 .
在光谱的另一端,我们可以重新加载页面 . 我们可以通过执行AJAX请求来执行此操作,然后在请求成功后单独重新加载页面(例如,使用
window.location.reload()
) . 我们也可以完全删除AJAX请求 . 相反,我们可以将表单提交给相关的更新URL . 服务器将对数据执行相关更改,然后返回新呈现的页面,最有可能使用res.render
调用,就像它对/
路径一样 .然后我们有两个解决方案,介于两者之间 .
我们仍然可以使用AJAX请求并更改响应,这样它不会返回JSON,而是返回HTML标记以注入页面的相关部分 . 我们需要使用合适的partial来分割服务器上的Handlebars模板,这样我们就可以生成我们需要的小部分HTML而不是整个页面的HTML .
另一个中间解决方案是在两端都有把手 . 数据仍将使用JSON加载,但它将通过浏览器中的Handlebars模板运行 . 要使其正常工作,您需要将相关的Handlebars JS文件加载到浏览器中 . 您还需要找到一种方法将相关模板放入浏览器,或者使用AJAX请求加载它,或者更可能在服务器上初始呈现页面时注入它 .
这是四种不同的方法,我们远远没有用尽可能性 . 鉴于这是一个学习练习,而不是一个现实世界的问题,实际上不可能打电话给哪种方法是最好的,每种方法都有利有弊 . 我认为最重要的是让你清楚服务器上运行什么代码以及客户端运行什么代码以及两者如何通过HTTP请求进行交互 .