Javascript res.writehead是否实际写入html页面的头部?
在我的node.js网页中,我制作了一个类似于Facebook链接预览的页面预览。我正在打电话获取页面的html,并使用它创建预览Javascript res.writehead是否实际写入html页面的头部?,javascript,jquery,html,node.js,Javascript,Jquery,Html,Node.js,在我的node.js网页中,我制作了一个类似于Facebook链接预览的页面预览。我正在打电话获取页面的html,并使用它创建预览 $.ajax({ type: 'GET', data: { "html": url }, url: "/htmlTest", success: function (data) { imgArray = []; $('img', data).each(function () {
$.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头写入底层TCP流。它与HTML完全无关
您遇到了一个问题,因为您的服务器返回了请求URL的全部HTML内容。然后将这个字符串传递到jQuery中,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,错误)
就可以了
else if (response.statusCode == 200) {
res.write(body);
res.end('\n');
}
在这里,我们可以用一个成功代码来回应。不要使用writeHead
,而是使用Express的set
和send
方法–将正确设置内容长度
等内容:
res.set('Content-Type', 'text/html');
res.send(body);
现在,如果response.statusCode!=200
?你不能处理那个案子<代码>错误仅在出现网络错误(例如无法连接到目标服务器)时设置。目标服务器仍然可以以非200状态响应,并且您的节点服务器永远不会响应浏览器。事实上,连接将一直保持打开状态,直到用户将其终止。这可以通过一个简单的else res.end()
来解决
即使解决了这些问题,我们仍然没有解决这样一个事实:在浏览器中解析任意HTML不是一个好主意 如果我是你,我会在服务器上使用某种东西将HTML解析成DOM,然后只将必要的信息作为JSON返回到浏览器。是您可能想要使用的模块–它看起来就像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
}
});
res.writeHead(200,{'content-type':'text/html'})代码>似乎只是在写一个标题(不是html内容),尽管我还没有深入到节点中。您的问题更可能是由res.write(body)引起的代码>你知道头是什么吗?我建议您学习并理解HTTP协议本身是如何工作的,因为尝试使用Node来提高任何效率。HTTP响应包含两个不同的部分-标题(内容类型/状态/等)和正文(实际有效负载)。是的,老实说,他们的文档听起来就是这样,但是css不知怎么进入了我的页面。writeHead
只写HTTP标题信息(状态、内容设置),而write
实际上是将您想要的内容写入您的网页。看起来您正在下载一个HTML页面,并返回整个HTML页面,其中包括
标记(css可能位于该位置)。谢谢!我有点自学成才,所以这个答案对我帮助很大。一个小编辑:(response.status!=200)应该是(response.statusCode!=200)