- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在我的 node.js 网页中,我正在制作类似于 Facebook 链接预览的页面预览。我正在调用以获取页面的 html,并使用它来创建预览。
$.ajax({
type: 'GET',
data: { "html": url },
url: "/htmlTest",
success: function (data) {
imgArray = [];
$('img', data).each(function () {
imgArray.push(this.src);
});
...
这是处理请求的服务器端代码。
app.get('/htmlTest', function (req, res) {
res.writeHead(200, { 'content-type': 'text/html' });
request(req.query.html, function (error, response, body) {
if (error) {
res.write(error.toString());
res.end('\n');
}
else if (response.statusCode == 200) {
res.write(body);
res.end('\n');
}
})
});
现在我注意到的是,它只会将其他页面使用的任何 css 插入到我的页面中,这真的会搞砸一切。为什么会这样?
此外,当我在做的时候,有没有人对 facebook 风格的页面预览有更好的想法?
最佳答案
没有。 writeHead
将 HTTP header 写入底层 TCP 流。它与 HTML 完全无关。
您遇到了问题,因为您的服务器返回所请求 URL 的批发 HTML 内容。然后将此字符串传递给 jQuery,这显然是将包含的 CSS 样式添加到您的文档中。
通常,从用户提供的 URL 中获取随机代码并在您的页面上下文中运行是一个糟糕的主意。它向您打开了巨大的安全漏洞 - 您看到的 CSS 工件就是一个例子。
坦率地说,您的代码有很多问题,请耐心等待我指出一些问题。
app.get('/htmlTest', function (req, res) {
res.writeHead(200, { 'content-type': 'text/html' });
在这里,您向浏览器响应成功状态 (200
) beore 您的服务器实际上执行任何操作。这是不正确的:只有在知道请求成功或失败后,您才应该使用成功或错误代码进行响应。
request(req.query.html, function (error, response, body) {
if (error) {
res.write(error.toString());
res.end('\n');
}
这里是用错误代码响应的好地方,因为我们知道请求确实失败了。 res.send(500, error)
就可以了。
else if (response.statusCode == 200) {
res.write(body);
res.end('\n');
}
这里是我们可以使用成功代码进行响应的地方。不要使用 writeHead
,而是使用 Express 的 set
和 send
方法——诸如 Content-Length
之类的东西将被正确设置:
res.set('Content-Type', 'text/html');
res.send(body);
现在如果 response.statusCode != 200
会发生什么?你不处理那个案子。 error
仅在网络错误的情况下设置(例如无法连接到目标服务器)。目标服务器仍然可以以非 200 状态响应,并且您的 Node 服务器永远不会响应浏览器。事实上,连接会挂起,直到用户终止它。这可以通过一个简单的 else res.end()
来解决。
即使解决了这些问题,我们仍然没有解决这样一个事实,即尝试在浏览器中解析任意 HTML 并不是一个好主意。
如果我是你,我会在服务器上使用将 HTML 解析为 DOM 的工具,然后只将必要的信息作为 JSON 返回给浏览器。 cheerio是您可能想要使用的模块——它看起来就像 jQuery,只是它在服务器上运行。
我会这样做:
var cheerio = require('cheerio'), url = require('url'), request = require('request');
app.get('/htmlTest', function(req, res) {
request(req.query.url, function(err, response, body) {
if (err) res.send(500, err); // network error, send a 500
else if (response.status != 200) res.send(500, { httpStatus: response.status }); // server returned a non-200, send a 500
else {
// WARNING! We should probably check that the response content-type is html
var $ = cheerio.load(body); // load the returned HTML into cheerio
var images = [];
$('img').each(function() {
// Image srcs can be relative.
// You probably need the absolute URL of the image, so we should resolve the src.
images.push(url.resolve(req.query.url, this.src));
});
res.send({ title: $('title').text(), images: images }); // send back JSON with the image URLs
}
});
});
然后从浏览器:
$.ajax({
url: '/htmlTest',
data: { url: url },
dataType: 'json',
success: function(data) {
// data.images has your image URLs
},
error: function() {
// something went wrong
}
});
关于javascript - res.writehead 实际上是写到我的 html 页面的头部吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19778791/
我正在使用 express并试图通过管道传输 req到远程服务器进行处理,然后通过 res 将结果通过管道传回客户端.它运行良好,但有时我认为 res由 connect-timeout 的操作结束,导
我正在尝试使用 fetch 进行简单的发布请求: const headers = new Headers({ Accept: 'application/json', 'Content-Type
我偶然发现了一个代码示例 here .引起我注意的行(跳过所有其他行): { ... void *res; ... s = pthread_join(tinfo[tnum].thread_id
我有一个 NodeJS 代码,使用请求模块向服务器发出请求。如果我使用“http.request”,代码工作正常,但在 res.on() 上显示错误使用请求来调用电话。以下是显示错误的部分: cons
我想知道这两种不同的方法在 expressjs 中是否相同? res.statusCode = 500; return res.json({ status: "error" }); 或者 r
我正在尝试在 Node.js 中制作简单的 ftp 客户端。一切正常,但我不知道如何在我的 Jade 模板中编写“singleFile.name”。 app.post('/ftp/login', fu
在frameworks/base下有这个xml文件。 /frameworks/base/core/res/res/layout/simple_dropdown_item_2line.xml 如何在我自
我是 odoo v8 的新手,我无法理解 res_partner 和 res_users 表之间的关系以及与 hr_employee 表之间的关系,它们都相关吗? 最佳答案 res.partner之间
我正在开发一个用于用户登录的小部件。基本上,当他们输入有效的帐户详细信息时,我希望它呈现相同的页面(使用 Handlebars )并声明“帐户已成功验证”之类的内容,然后 3 秒后重定向用户。 这是我
我有这种形式的数据 [ { device_id: '12335', timestamp: '2018-05-14T08:31:23.000Z', temperatur: 21,
我是 android 开发的新手,您可能会从我的问题中看出这一点。我发现我有一个 res/menu 文件夹和一个 res/layout 文件夹。它们都包含每个 Activity 的 XML 文件。但是
当我尝试按照指南中的说明在 res/menu 中创建新的菜单资源文件时,该文件夹不存在。 res/xml 也不是。有人可以告诉我如何解决这个问题吗?我尝试创建文件夹,但它不允许我这样做 最佳答案 如果
调用有什么区别: res.flushBuffer(); 对比 res.getOutputStream().flush(); 这些方法是否刷新相同的缓冲区? 如果是这样,你能告诉我这个缓冲区是如何由
为什么以下不起作用? res.send({ successMessage: 'Task saved successfully.' }); res.redirect('/'); 我基本上需要 A
我正在尝试确定是否可以同时调用 res.send(data) 和 res.render('reports')。 为了进一步详细解释,当我路由到“/reports”时,首先在我的服务器端我对返回 jso
app.get('/p/:tagId', function(req, res) { res.send("tagId is set to " + req.param("tagId")); }); 上
我在使用express.js 时遇到一些问题。我想在第一次请求时渲染我的模板,然后从路由中获取一些数据。我的路由如下所示: app.use(function (req, res, next) { r
我想根据屏幕尺寸加载 dimens.xml,但无论屏幕尺寸如何都使用相同的颜色。 我有以下目录结构 res res/values colors.xml res/values-small d
我有一张图片,rectangle.png。它的尺寸是 75x197。它位于 res/drawable 和 res/drawable-xhdpi。它在像这样的网格布局中显示了很多次(截图来自 Nexus
我很好奇返回响应和仅创建响应的区别。 我见过大量使用 return res.status(xxx).json(x) 的代码示例和res.status(xxx).json(x) . 谁能详细解释一下两者
我是一名优秀的程序员,十分优秀!