res.writehead是否真的写到我的html页面的头部
Does res.writehead actually write to the head of my html page?
在我的节点.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风格的页面预览有更好的想法?
No. writeHead
将 HTTP 标头写入基础 TCP 流。 它与HTML完全无关。
您遇到了问题,因为您的服务器返回了所请求 URL 的批发 HTML 内容。 然后将此字符串传递到 jQuery,这显然是在将包含的 CSS 样式添加到您的文档中。
通常,从用户提供的 URL 中获取随机代码并在页面上下文中运行是一个糟糕的主意。 它为你打开了巨大的安全漏洞 - 你看到的CSS工件就是一个例子。
坦率地说,你的代码有很多问题,所以请耐心等待我指出一些问题。
app.get('/htmlTest', function (req, res) {
res.writeHead(200, { 'content-type': 'text/html' });
在这里,您以成功状态(200
)响应浏览器,因为您的服务器实际上执行了任何操作。 这是不正确的:只有在知道请求是成功还是失败后,才应使用成功或错误代码进行响应。
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 状态进行响应,并且节点服务器永远不会响应浏览器。 事实上,连接将挂起,直到用户杀死它。 这可以通过一个简单的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
}
});
- HTML文档中脚本标记的位置-<头部>&<身体>有不同的行为
- 在HTML JavaScript头部分运行Google脚本函数
- 如何在不包含导航选项卡内容、页脚和头部的情况下打印 HTML/PHP 页面
- res.writehead是否真的写到我的html页面的头部
- 弹出窗口.js 未在 Chrome 扩展程序中的 Popup 的头部标签中执行.html Popup
- 如何维护HTML头部/正文块加载到流星应用程序的顺序
- 在弹出窗口中显示完整的 html(元、头部、正文)
- HTML页面头部出现Javascript代码问题
- 使用JavaScript将样式表附加到html文档的头部
- 如何在每个</头部>在多个HTML页面站点中
- HTML尾部标记以补充头部标记
- 如何将.css和.js文件链接到丢失的HTML<html>并且<头部>标签
- 将数据从头部的JavaScript传输到主体的html
- 将css文件注入HtmlWebpackPlugin生成的html文件的头部
- 模拟头部HTML导入
- Js外部是不工作的头部标签的html
- AJAX html存根——加载清除头部元素实用吗?
- 结合jQuery表和头部:如何分配最终的html输出
- 在HTML头部获取js文件是不工作的
- 我可以将Javascript字符串附加到HTML头部元素吗?