否。 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
}
});