Javascript res.writehead是否实际写入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 () {

在我的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头写入底层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)