Hantar satu respons yang berjaya, tulis isinya secara berperingkat dan tamatkan mesej seperti biasa. Panduan Terminal Mac ini menunjukkan cara menghantar dokumen sintetik yang lengkap tanpa menganggap setiap cebisan sebagai respons berasingan atau menggunakan 206 Partial Content.
Tugasnya adalah untuk menyediakan satu halaman HTML yang dimaksudkan untuk pengehosan awam, kemudian mengesahkan bahawa klien menerima kandungannya yang lengkap. Demonstrasi ini dijalankan secara setempat dan tidak menerbitkan apa-apa. Anda memerlukan Terminal, curl dan keluaran LTS Node.js yang disokong daripada halaman muat turun rasmi Node.js.
Mengapa cebisan tidak bermaksud respons separa
Maksud respons dan pembingkaian penghantarannya menjawab soalan yang berbeza. Untuk GET biasa yang berjaya, 200 OK menandakan pengambilan berjaya. 206 Partial Content bermaksud pelayan memenuhi permintaan julat dengan memindahkan bahagian terpilih daripada suatu perwakilan. Membahagikan penghantaran kepada beberapa penulisan tidak menghasilkan permintaan julat. RFC 9110: Semantik HTTP, 206 Partial Content.
Sebagai contoh, panduan sintetik yang mengandungi pengenalan, huraian dan perenggan penutup boleh diterima secara berperingkat sambil kekal sebagai satu dokumen. Hantar pengepala responsnya sekali, kemudian bahagian isi tersebut mengikut turutan. Jangan tambah baris status HTTP baharu sebelum setiap bahagian.
Pengekodan pemindahan bercebisan HTTP/1.1 membalut bait isi dengan panjang dalam perenambelasan dan berakhir dengan cebisan bersaiz sifar serta baris kosong penamat yang diwajibkan. Bait pembingkaian itu membatasi penghantaran; ia bukan kandungan artikel. Penghantar tidak boleh menggabungkan Content-Length dengan Transfer-Encoding. RFC 9112: Pengekodan Pemindahan Bercebisan, Content-Length.
Peraturan praktikalnya adalah membiarkan pustaka HTTP membingkaikan mesej. Aplikasi anda membekalkan kandungan dokumen dan menandakan apabila kandungan itu selesai.
Mekanisme penstriman yang manakah patut anda gunakan?
Mekanisme yang disokong bergantung pada versi HTTP. Penstriman isi lengkap masih boleh dilakukan dalam ketiga-tiga versi di bawah, tetapi pembingkaiannya berbeza.
| Versi HTTP | Cara kandungan isi dihantar | Mekanisme penyiapan |
|---|---|---|
| HTTP/1.1 dengan pengekodan bercebisan | Cebisan berawalan panjang | Cebisan terminal bersaiz sifar dan bahagian treler yang lengkap |
| HTTP/2 | Bingkai DATA |
END_STREAM pada bingkai penutup, termasuk penyiapan sebarang blok pengepala |
| HTTP/3 | Bingkai DATA |
Penyiapan respons dan penutupan arah penghantaran strim |
HTTP/2 secara jelas tidak membenarkan pengekodan pemindahan bercebisan HTTP/1.1. HTTP/3 tidak mentakrifkan pengekodan pemindahan dan melarang pengepala Transfer-Encoding. Biarkan pelayan melaksanakan pembingkaian protokolnya sendiri dan jangan paksa Transfer-Encoding: chunked pada setiap sambungan. RFC 9113: Pertukaran Mesej HTTP, RFC 9114: Pembingkaian Mesej HTTP.
Untuk dokumen kecil yang sudah dihimpunkan, menghantarnya seperti biasa biasanya merupakan pelaksanaan yang paling mudah. Penulisan secara berperingkat berguna apabila kandungan dihasilkan dari semasa ke semasa. Contoh di bawah sengaja menjeda antara tiga penulisan supaya anda boleh memerhatikan tingkah lakunya; jeda itu sekadar ilustrasi, bukan saranan penerbitan.
Mulakan dokumen penstriman lengkap pada Mac anda
Buka Terminal dan semak prasyarat:
node --version
curl --version
Jika node tidak tersedia, pasang keluaran LTS yang disokong menggunakan halaman muat turun Node.js, kemudian buka tetingkap Terminal baharu. Program ini hanya menggunakan modul terbina dalam dan tidak memerlukan pakej npm.
Tampal keseluruhan blok di bawah ke dalam Terminal. Ia memulakan pelayan HTTP/1.1 di alamat demonstrasi http://127.0.0.1:8080/document. Ketiga-tiga rentetan itu bersama-sama membentuk satu halaman sintetik yang lengkap.
node <<'JS'
const http = require('node:http');
const parts = [
'<!doctype html>\n<html lang="en"><head><meta charset="utf-8">' +
'<title>Paper Shapes</title></head><body><main>\n' +
'<h1>Paper Shapes</h1>\n',
'<p>A circle, a square, and a triangle make this sample collection.</p>\n',
'<p>End of the paper shapes guide.</p>\n</main></body></html>\n'
];
const server = http.createServer((req, res) => {
res.on('error', error => console.error(error.message));
if (req.method !== 'GET' || req.url !== '/document') {
res.writeHead(404, { 'Content-Type': 'text/plain; charset=utf-8' });
res.end('No sample document at this path.\n');
return;
}
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
let index = 0;
const timer = setInterval(() => {
if (res.destroyed) {
clearInterval(timer);
return;
}
res.write(parts[index++]);
if (index === parts.length) {
clearInterval(timer);
res.end();
}
}, 300);
res.on('close', () => clearInterval(timer));
});
server.on('error', error => {
console.error(error.message);
process.exitCode = 1;
});
server.listen(8080, '127.0.0.1', () => {
console.log('Sample: http://127.0.0.1:8080/document');
});
JS
Aplikasi memanggil writeHead() sekali, write() tiga kali dan end() sekali. Dokumentasi Node menerangkan bahawa penulisan berturutan ialah bahagian daripada isi respons yang sama dan menghendaki end() untuk melengkapkan setiap respons. Node mengendalikan pembingkaian HTTP; jangan tambah panjang cebisan atau sifar terminal pada rentetan tersebut. Dokumentasi HTTP Node.js.
Ini ialah demonstrasi terhad dengan tiga rentetan kecil. Bagi pengeluar data yang besar atau berterusan, patuhi kawalan aliran balik: apabila write() memulangkan false, jedakan penghasilan sehingga drain, sambil turut mengendalikan penutupan dan ralat. Dokumentasi penulisan respons Node.js.
Biarkan tetingkap Terminal ini terus berjalan. Jika ia melaporkan EADDRINUSE, port 8080 sedang digunakan; pilih port lain yang tersedia pada pelayan dan ubah port dalam setiap arahan klien di bawah. Hentikan demonstrasi dengan Control-C apabila selesai.
Periksa kandungan yang dinyahkod dan pembingkaian cebisan HTTP
Dalam tetingkap Terminal kedua, minta dokumen tersebut:
curl --http1.1 --include --no-buffer --max-time 5 \
http://127.0.0.1:8080/document
Jangkakan satu respons 200 OK, Content-Type bernilai text/html; charset=utf-8 dan kandungan halaman yang telah dihimpunkan. Untuk contoh HTTP/1.1 ini, respons sepatutnya menggunakan Transfer-Encoding: chunked. Curl biasanya menyahkod pembingkaian pemindahan, jadi output biasanya memaparkan dokumen dan bukannya saiz cebisan perenambelasan.
Untuk memeriksa pembingkaian, ulangi permintaan dengan --raw:
curl --http1.1 --include --no-buffer --raw --max-time 5 \
http://127.0.0.1:8080/document
Dokumentasi curl menerangkan bahawa --raw melumpuhkan penyahkodan dalaman kandungan dan pengekodan pemindahan. --no-buffer melumpuhkan penimbalan output curl, manakala --max-time 5 mengehadkan tempoh operasi. Pilihan ini menjadikan arahan tersebut diagnostik ringkas dan bukannya arahan yang menunggu tanpa had. Manual curl.
Dalam output mentah, baris saiz mengelilingi kandungan, diikuti cebisan penamat bersaiz sifar. Tanpa penamat itu, isi HTTP/1.1 bercebisan tidak lengkap. Dengan pembingkaian panjang tetap, menerima bait yang lebih sedikit daripada panjang yang diisytiharkan bermakna mesej tidak lengkap. RFC 9112: Pengendalian Mesej Tidak Lengkap.
Gunakan output mentah hanya untuk memeriksa pengangkutan. Jangan salin baris saiznya ke dalam fail halaman atau menganggapnya sebagai bahagian dokumen.
Terima keseluruhan dokumen sebelum memprosesnya
Jika langkah seterusnya memerlukan halaman yang lengkap, baca keseluruhan isi sebelum menghuraikan, menyimpan atau menerimanya. WHATWG mentakrifkan isi respons sebagai strim; kaedah text() membaca keseluruhan isi itu dan memulangkan rentetan, serta menolak permintaan apabila penggunaan isi gagal. Menerima pengepala respons sahaja tidak membuktikan bahawa isi telah selesai. Piawaian Fetch WHATWG: Mixin Body, Pemprosesan respons.
Dengan pelayan masih berjalan, tampal keseluruhan klien ini ke dalam tetingkap Terminal kedua:
node --input-type=module <<'JS'
try {
const response = await fetch('http://127.0.0.1:8080/document', {
signal: AbortSignal.timeout(5000)
});
if (response.status !== 200) {
throw new Error(`Expected 200; received ${response.status}`);
}
const html = await response.text();
const marker = 'End of the paper shapes guide.';
if (!html.includes(marker) || !html.endsWith('</html>\n')) {
throw new Error('Expected sample ending is missing');
}
console.log(html);
console.log('Complete sample document received.');
} catch (error) {
console.error('Document not accepted:', error.message);
process.exitCode = 1;
}
JS
Node menyediakan pelaksanaan fetch() yang serasi dengan pelayar. AbortSignal.timeout() mencipta isyarat yang membatalkan operasi selepas bilangan milisaat yang ditetapkan; di sini, lima saat ialah had ilustrasi untuk contoh setempat yang kecil ini. Dokumentasi objek global Node.js, Dokumentasi tamat masa AbortSignal.
Klien menyemak dua perkara yang berbeza: penggunaan isi yang berjaya dan pengakhiran sampel yang dijangka. Semakan kedua itu ialah diagnostik khusus aplikasi. HTTP boleh berjaya memindahkan dokumen yang dipendekkan secara tidak sengaja oleh aplikasi anda sebelum memanggil end(). Penanda penyiapan membantu mengesan kesilapan khusus itu, tetapi tidak mengesahkan setiap perenggan atau menjadi pengesahan HTML umum.
Klien ini menimbal keseluruhan halaman dalam ingatan. Untuk dokumen yang sangat besar, pilih pemprosesan berperingkat dengan format dokumen dan peraturan penyiapan yang jelas. Jangan anggap setiap bacaan menerima satu perenggan lengkap atau respons yang bermakna secara berasingan.
Diagnosis penyiapan sebelum menukar kod status
Gunakan urutan ini untuk mencari punca masalah. Urutan ini memisahkan penyiapan pengangkutan daripada kandungan yang dimaksudkan oleh aplikasi, supaya muat turun yang kelihatan berjaya tidak menyembunyikan pengakhiran yang tertinggal.
| Pemerhatian | Tindakan seterusnya |
|---|---|
| Arahan setempat tidak dapat disambungkan | Pastikan pelayan sedang berjalan dan portnya sepadan. |
| Curl tamat masa | Pastikan pengeluar data selesai dan memanggil end(); simpan output ralat. |
| Pemindahan selesai tetapi semakan pengakhiran gagal | Periksa kandungan yang dijana dan titik aplikasi menamatkan respons. |
| Dokumen lengkap tiba serentak | Bandingkan output mentah dan output yang dinyahkod; jangan membuat kesimpulan bahawa terdapat berbilang respons berdasarkan masa paparan. |
Permintaan halaman penuh biasa menerima 206 |
Periksa sama ada pengendalian julat telah digunakan secara tidak sengaja; penghantaran berperingkat sahaja tidak membenarkannya. |
Semakan penyiapan ini ialah saranan yang diperoleh daripada protokol dan tingkah laku Fetch, bukannya ciri HTTP yang berasingan. Jika operasi membaca isi gagal, klien di atas melaporkan kegagalan dan keluar dengan status gagal dan bukannya memaparkan mesej kejayaan untuk kandungan yang diterima setakat itu.
Apakah maknanya untuk halaman awam dan Google Search?
Kekalkan kandungan dokumen yang berguna dalam respons HTML itu sendiri. Google menerangkan bahawa perayapan dan penghuraian berfungsi dengan baik untuk halaman yang HTML responsnya mengandungi semua kandungan, serta menyarankan pemaparan sisi pelayan atau prapemaparan kerana bukan semua bot menjalankan JavaScript. Sampel ini mengikut pendekatan tersebut: teksnya tiba terus dalam isi dokumen. Google Search Central: Fahami asas SEO JavaScript.
Dokumentasi perayap Google menyatakan bahawa respons 200 meneruskan kandungan yang diterima ke peringkat pemprosesan seterusnya; ia tidak menjamin pengindeksan. Dokumentasi yang dirujuk tidak menyatakan saiz cebisan atau jeda khas yang memastikan halaman akan diindeks. Anggap penstriman sebagai pelaksanaan penghantaran dan sahkan kandungan yang lengkap secara berasingan. Google: Cara kod status HTTP mempengaruhi perayap Google.
Apabila mengadaptasi demonstrasi ini untuk pengehosan awam, ulangi semakan pada titik akhir dokumen sebenar. Sahkan status kejayaan, baca keseluruhan isi dan bandingkan kandungan akhirnya dengan halaman yang dimaksudkan. Pastikan semakan penerimaan tidak bergantung pada bilangan penulisan, bingkai atau kemas kini yang kelihatan yang digunakan untuk menghantar dokumen.
Sumber
- RFC 9110: Semantik HTTP — RFC Editor / IETF.
- RFC 9112: HTTP/1.1 — RFC Editor / IETF.
- RFC 9113: HTTP/2 — RFC Editor / IETF.
- RFC 9114: HTTP/3 — RFC Editor / IETF.
- Piawaian Fetch — WHATWG.
- HTTP — Node.js.
- Objek global — Node.js.
- Muat turun Node.js — Node.js.
- curl — Cara Penggunaan — curl.
- Fahami asas SEO JavaScript — Google Search Central.
- Cara kod status HTTP mempengaruhi perayap Google — Google for Developers.