writeHead
基になる TCP ストリームに HTTP ヘッダーを書き込みます。 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
}
});