Node.js adalah platform server. Tugas utama server adalah untuk memproses permintaan dari klien, khususnya, dari browser, secepat dan seefisien mungkin. Terjemahan kedelapan dari tutorial Node.js yang kami terbitkan hari ini adalah tentang HTTP dan WebSocket.

[Kami menyarankan Anda untuk membaca] Bagian lain dari siklus iniBagian 1:
Informasi Umum dan MemulaiBagian 2:
JavaScript, V8, beberapa trik pengembanganBagian 3:
Hosting, REPL, bekerja dengan konsol, modulBagian 4:
npm, package.json dan file package-lock.jsonBagian 5:
npm dan npxBagian 6:
loop acara, tumpukan panggilan, timerBagian 7:
Pemrograman AsinkronBagian 8:
Panduan Node.js, Bagian 8: HTTP dan Protokol WebSocketBagian 9:
Panduan Node.js, bagian 9: bekerja dengan sistem fileBagian 10:
Panduan Node.js, Bagian 10: Modul Standar, Streaming, Database, NODE_ENVPDF lengkap dari Node.js Guide Apa yang terjadi ketika membuat permintaan HTTP?
Mari kita bicara tentang bagaimana browser membuat permintaan ke server menggunakan protokol HTTP / 1.1.
Jika Anda pernah memiliki wawancara di bidang TI, maka Anda mungkin akan ditanya apa yang terjadi ketika Anda mengetik sesuatu di bilah alamat browser Anda dan tekan Enter. Mungkin ini adalah salah satu pertanyaan paling populer yang terjadi pada wawancara semacam itu. Siapa pun yang mengajukan pertanyaan seperti itu ingin tahu apakah Anda dapat menjelaskan beberapa konsep yang cukup sederhana dan mencari tahu apakah Anda memahami prinsip-prinsip Internet.
Pertanyaan ini menyentuh banyak teknologi, untuk memahami prinsip-prinsip umum yang berarti memahami bagaimana salah satu sistem paling rumit yang pernah dibangun oleh umat manusia dibangun, yang mencakup seluruh dunia.
▍ Protokol HTTP
Browser modern dapat membedakan URL asli yang dimasukkan ke dalam bilah alamat mereka dari permintaan pencarian, untuk pemrosesan yang biasanya digunakan oleh mesin pencari standar. Kami akan berbicara tentang URL. Jika Anda memasukkan alamat situs web, seperti
flaviocopes.com
, ke dalam baris peramban, peramban mengonversi alamat ini ke formulir
http://flaviocopes.com
, berdasarkan asumsi bahwa protokol HTTP akan digunakan untuk bertukar data dengan sumber daya yang ditentukan. Harap dicatat bahwa pada Windows, apa yang akan kita bicarakan di sini mungkin terlihat sedikit berbeda dari pada macOS dan Linux.
▍ Fase pencarian DNS
Jadi, browser, mulai bekerja mengunduh data dari alamat yang diminta oleh pengguna, melakukan operasi Pencarian DNS (Pencarian DNS) untuk mengetahui alamat IP dari server terkait. Nama simbolis dari sumber daya yang dimasukkan di bilah alamat nyaman untuk orang, tetapi perangkat Internet menyiratkan kemungkinan pertukaran data antara komputer menggunakan alamat IP, yang merupakan kumpulan angka seperti 222.324.3.1 (untuk IPv4).
Pertama, mencari tahu alamat IP server, browser melihat ke cache DNS lokal untuk melihat apakah prosedur serupa telah dilakukan baru-baru ini. Di browser Chrome, misalnya, ada cara mudah untuk melihat cache DNS dengan memasukkan alamat berikut di bilah alamat:
chrome://net-internals/#dns
.
Jika tidak ada yang dapat ditemukan di cache, browser menggunakan panggilan sistem
gethostbyname
POSIX untuk mengetahui alamat IP server.
▍ fungsi gethostbyname
Fungsi
gethostbyname
pertama-tama memeriksa
hosts
, yang, pada macOS atau Linux, dapat ditemukan di
/etc/hosts
untuk mencari tahu apakah informasi lokal dapat ditemukan dengan mencari tahu alamat server.
Jika lokal berarti menyelesaikan permintaan untuk mengetahui alamat IP server gagal, sistem melakukan permintaan ke server DNS. Alamat server tersebut disimpan dalam pengaturan sistem.
Berikut adalah beberapa server DNS populer:
- 8.8.8.8: Server Google DNS.
- 1.1.1.1: Server CloudFlare DNS.
Kebanyakan orang menggunakan server DNS yang disediakan oleh penyedia mereka. Browser melakukan permintaan DNS menggunakan protokol UDP.
TCP dan UDP adalah dua protokol dasar yang digunakan dalam jaringan komputer. Mereka berada pada level konseptual yang sama, tetapi TCP adalah protokol berorientasi koneksi, dan untuk pertukaran pesan UDP, pemrosesan yang menciptakan beban tambahan kecil pada sistem, prosedur pembentukan koneksi tidak diperlukan. Kami tidak akan berbicara tentang bagaimana pertukaran data dengan UDP.
Alamat IP yang sesuai dengan nama domain yang menarik bagi kami mungkin ada dalam cache server DNS. Jika ini bukan masalahnya, ia akan menghubungi server DNS root. Sistem DNS root server terdiri dari 13 server, di mana pengoperasian seluruh Internet tergantung.
Perlu dicatat bahwa root DNS server tidak mengetahui korespondensi antara semua nama domain dan alamat IP yang ada di dunia. Tetapi server yang sama mengetahui alamat server DNS tingkat atas untuk domain seperti .com, .it, .pizza, dan sebagainya.
Setelah menerima permintaan, root DNS server mengarahkan ulang ke server DNS dari domain tingkat atas, ke server TLD (dari Top-Level Domain).
Misalkan browser sedang mencari alamat IP untuk server
flaviocopes.com
. Beralih ke root DNS server, browser akan menerima alamat server TLD untuk zona .com darinya. Sekarang alamat ini akan disimpan dalam cache, sebagai hasilnya, jika Anda perlu mengetahui alamat IP dari URL lain dari zona .com, Anda tidak perlu menghubungi server DNS root lagi.
Server TLD memiliki alamat IP server nama (Name Server, NS), dengan bantuan yang Anda dapat mengetahui alamat IP dari URL yang kami miliki. Di mana server NS mendapatkan informasi ini? Faktanya adalah bahwa jika Anda membeli domain, pendaftar domain mengirimkan data tentangnya ke server nama. Prosedur serupa dilakukan, misalnya, ketika mengubah hosting.
Server yang dimaksud biasanya dimiliki oleh penyedia hosting. Sebagai aturan, untuk melindungi dari kegagalan, beberapa server dibuat. Misalnya, mereka mungkin memiliki alamat ini:
- ns1.dreamhost.com
- ns2.dreamhost.com
- ns3.dreamhost.com
Untuk mengetahui alamat IP dengan URL, pada akhirnya, mereka beralih ke server tersebut. Mereka menyimpan data aktual tentang alamat IP.
Sekarang, setelah kami berhasil menemukan alamat IP di belakang URL yang dimasukkan di bilah alamat browser, kami beralih ke langkah selanjutnya dari pekerjaan kami.
▍ Membuat koneksi TCP
Setelah mempelajari alamat IP server, klien dapat memulai koneksi TCP ke sana. Dalam proses membangun koneksi TCP, klien dan server mengirimkan satu sama lain beberapa data layanan, setelah itu mereka dapat bertukar informasi. Ini berarti bahwa setelah koneksi dibuat, klien akan dapat mengirim permintaan ke server.
▍Mengirim permintaan
Permintaan adalah fragmen teks yang disusun sesuai dengan aturan protokol yang digunakan. Ini terdiri dari tiga bagian:
- String kueri
- Minta tajuk.
- Meminta badan.
String kueri
String kueri adalah string teks tunggal yang berisi informasi berikut:
- Metode HTTP.
- Alamat Sumber Daya
- Versi protokol.
Mungkin terlihat, misalnya, seperti ini:
GET / HTTP/1.1
Minta tajuk
Header permintaan diwakili oleh seperangkat
:
. Ada 2 bidang header yang diperlukan, salah satunya adalah
Host
dan yang kedua adalah
Connection
. Kolom yang tersisa adalah opsional.
Judulnya mungkin terlihat seperti ini:
Host: flaviocopes.com Connection: close
Bidang
Host
menunjukkan nama domain yang diminati browser. Bidang
Connection
, diatur ke
close
, berarti koneksi antara klien dan server tidak perlu tetap terbuka.
Header permintaan yang umum digunakan meliputi:
Origin
Accept
Accept-Encoding
Cookie
Cache-Control
Dnt
Padahal, masih banyak lagi.
Header permintaan berakhir dengan string kosong.
Meminta badan
Badan permintaan bersifat opsional, tidak digunakan dalam permintaan GET. Badan permintaan digunakan dalam permintaan POST, serta dalam permintaan lainnya. Ini mungkin berisi, misalnya, data dalam format JSON.
Karena sekarang kita berbicara tentang permintaan GET, badan permintaan akan kosong, kami tidak akan bekerja dengannya.
▍ Jawab
Setelah server menerima permintaan yang dikirim oleh klien, ia memprosesnya dan mengirimkan respons kepada klien.
Respons dimulai dengan kode status dan pesan yang sesuai. Jika permintaan berhasil, awal respons akan terlihat seperti ini:
200 OK
Jika ada kesalahan, mungkin ada kode lain. Misalnya, berikut ini:
404 Not Found
403 Forbidden
301 Moved Permanently
500 Internal Server Error
304 Not Modified
401 Unauthorized
Selanjutnya, respons berisi daftar tajuk HTTP dan isi respons (yang, karena permintaan dieksekusi oleh browser, akan berupa kode HTML).
Penguraian HTML
Setelah browser menerima respons dari server, yang bodinya berisi kode HTML, ia mulai menguraikannya, mengulangi proses di atas untuk setiap sumber daya yang diperlukan untuk membentuk halaman. Sumber daya tersebut meliputi, misalnya, yang berikut:
- File CSS.
- Gambar
- Ikon halaman web (favicon).
- File JavaScript.
Bagaimana tepatnya browser menampilkan halaman tidak berlaku untuk percakapan kami. Hal utama yang menarik bagi kami di sini adalah bahwa proses meminta dan menerima data di atas digunakan tidak hanya untuk kode HTML, tetapi juga untuk objek lain yang ditransfer dari server ke browser menggunakan protokol HTTP.
Tentang membuat server sederhana menggunakan Node.js
Sekarang, setelah kami memeriksa proses interaksi antara browser dan server, Anda dapat melihat segar di bagian aplikasi First Node.js dari bagian
pertama dari rangkaian materi ini, di mana kami menggambarkan kode untuk server sederhana.
Membuat permintaan HTTP dengan Node.js
Untuk melakukan permintaan HTTP menggunakan Node.js,
modul yang sesuai
digunakan . Contoh di bawah ini menggunakan modul
https . Faktanya adalah bahwa dalam kondisi modern, bila memungkinkan, perlu untuk menggunakan protokol HTTPS.
▍ Mengeksekusi permintaan GET
Berikut adalah contoh menjalankan permintaan GET menggunakan Node.js:
const https = require('https') const options = { hostname: 'flaviocopes.com', port: 443, path: '/todos', method: 'GET' } const req = https.request(options, (res) => { console.log(`statusCode: ${res.statusCode}`) res.on('data', (d) => { process.stdout.write(d) }) }) req.on('error', (error) => { console.error(error) }) req.end()
▍POST eksekusi permintaan
Berikut cara membuat permintaan POST dari Node.js:
const https = require('https') const data = JSON.stringify({ todo: 'Buy the milk' }) const options = { hostname: 'flaviocopes.com', port: 443, path: '/todos', method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': data.length } } const req = https.request(options, (res) => { console.log(`statusCode: ${res.statusCode}`) res.on('data', (d) => { process.stdout.write(d) }) }) req.on('error', (error) => { console.error(error) }) req.write(data) req.end()
▍PUT dan HAPUS pertanyaan
Eksekusi permintaan seperti itu terlihat sama dengan eksekusi permintaan POST. Perbedaan utama, selain konten semantik dari operasi tersebut, adalah nilai properti
method
dari objek
options
.
▍ Melakukan permintaan HTTP di Node.js menggunakan perpustakaan Axios
Axios adalah pustaka JavaScript yang sangat populer yang berfungsi baik di browser (ini mencakup semua browser modern dan IE, dimulai dengan IE8), dan di lingkungan Node.js, yang dapat digunakan untuk melakukan permintaan HTTP.
Perpustakaan ini didasarkan pada janji-janji, ia memiliki beberapa keunggulan dibandingkan mekanisme standar, khususnya, lebih dari API Fetch. Di antara kelebihannya adalah sebagai berikut:
- Dukungan untuk browser lama (Anda perlu polyfill untuk menggunakan Ambil).
- Kemampuan untuk menginterupsi permintaan.
- Dukungan untuk mengatur batas waktu permintaan.
- Perlindungan bawaan terhadap serangan CSRF.
- Dukungan untuk mengunggah data dengan ketentuan informasi tentang kemajuan proses ini.
- Dukungan untuk konversi data JSON.
- Pekerjaan di Node.js
Instalasi
Anda dapat menggunakan npm untuk menginstal Axios:
npm install axios
Efek yang sama dapat dicapai dengan benang:
yarn add axios
Anda dapat menghubungkan perpustakaan ke halaman menggunakan
unpkg.com
:
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
API Axios
Anda dapat membuat permintaan HTTP menggunakan objek
axios
:
axios({ url: 'https://dog.ceo/api/breeds/list/all', method: 'get', data: { foo: 'bar' } })
Tetapi biasanya lebih nyaman menggunakan metode khusus:
Ini mirip dengan bagaimana jQuery menggunakan
$.get()
dan
$.post()
alih-alih
$.ajax()
$.post()
.
Axios menawarkan metode terpisah untuk mengeksekusi jenis permintaan HTTP lain, yang tidak sepopuler GET dan POST, tetapi masih digunakan:
axios.delete()
axios.put()
axios.patch()
axios.options()
Perpustakaan memiliki metode untuk mengeksekusi permintaan yang dirancang untuk hanya menerima tajuk HTTP, tanpa badan respons:
DAPATKAN permintaan
Axios nyaman digunakan menggunakan sintaksis async / await modern. Contoh kode berikut, yang dirancang untuk Node.js, menggunakan perpustakaan untuk memuat daftar trah anjing dari
Dog API . Di sini metode
axios.get()
diterapkan dan batuan dihitung:
const axios = require('axios') const getBreeds = async () => { try { return await axios.get('https://dog.ceo/api/breeds/list/all') } catch (error) { console.error(error) } } const countBreeds = async () => { const breeds = await getBreeds() if (breeds.data.message) { console.log(`Got ${Object.entries(breeds.data.message).length} breeds`) } } countBreeds()
Hal yang sama dapat ditulis ulang tanpa menggunakan async / menunggu, menerapkan janji:
const axios = require('axios') const getBreeds = () => { try { return axios.get('https://dog.ceo/api/breeds/list/all') } catch (error) { console.error(error) } } const countBreeds = async () => { const breeds = getBreeds() .then(response => { if (response.data.message) { console.log( `Got ${Object.entries(response.data.message).length} breeds` ) } }) .catch(error => { console.log(error) }) } countBreeds()
Menggunakan parameter dalam permintaan GET
Permintaan GET dapat berisi parameter yang terlihat seperti ini di URL:
https:
Saat menggunakan Axios, permintaan semacam ini dapat dilakukan seperti ini:
axios.get('https:
Efek yang sama dapat dicapai dengan mengatur properti
params
di objek dengan parameter:
axios.get('https://site.com/', { params: { foo: 'bar' } })
Permintaan POST
Mengeksekusi permintaan POST sangat mirip dengan mengeksekusi permintaan GET, tetapi di sini, alih-alih metode
axios.get()
, metode
axios.post()
digunakan:
axios.post('https:
Sebagai argumen kedua, metode
post
menerima objek dengan parameter permintaan:
axios.post('https://site.com/', { foo: 'bar' })
Menggunakan Protokol WebSocket di Node.js
WebSocket adalah alternatif untuk HTTP, dapat digunakan untuk mengatur pertukaran data dalam aplikasi web. Protokol ini memungkinkan Anda untuk membuat saluran komunikasi dua arah yang berumur panjang antara klien dan server. Setelah koneksi dibuat, saluran komunikasi tetap terbuka, yang menempatkan aplikasi pada pembuangan koneksi yang sangat cepat, ditandai dengan latensi rendah dan beban tambahan kecil pada sistem.
Protokol WebSocket didukung oleh semua browser modern.
▍ Perbedaan HTTP
HTTP dan WebSocket adalah protokol yang sangat berbeda yang menggunakan pendekatan berbeda untuk bertukar data. HTTP didasarkan pada model "permintaan-respons": server mengirim beberapa data ke klien setelah diminta. Dalam kasus WebSocket, semuanya diatur secara berbeda. Yaitu:
- Server dapat mengirim pesan ke klien atas inisiatifnya sendiri, tanpa menunggu permintaan dari klien.
- Klien dan server dapat bertukar data secara bersamaan.
- Saat mengirimkan pesan, sejumlah kecil data layanan digunakan. Ini, khususnya, menyebabkan latensi rendah dalam pengiriman data.
Protokol WebSocket sangat cocok untuk komunikasi real-time melalui saluran yang tetap terbuka untuk waktu yang lama. HTTP, pada gilirannya, sangat baik untuk mengatur sesi komunikasi sesekali yang diprakarsai oleh klien. Pada saat yang sama, harus dicatat bahwa, dari sudut pandang pemrograman, jauh lebih mudah untuk mengimplementasikan pertukaran data menggunakan protokol HTTP daripada menggunakan protokol WebSocket.
▍ Versi protokol WebSocket yang dilindungi
Ada versi yang tidak aman dari protokol WebSocket (
ws://
skema URI), yang menyerupai, dalam hal keamanan, protokol
http://
. Penggunaan
ws://
harus dihindari, lebih memilih versi protokol yang aman -
wss://
.
▍Membuat Koneksi WebSocket
Untuk membuat koneksi WebSocket, Anda perlu menggunakan
konstruktor yang sesuai:
const url = 'wss://myserver.com/something' const connection = new WebSocket(url)
Setelah koneksi berhasil dibuat, acara
open
dinaikkan. Anda dapat mengatur acara ini dengan menetapkan fungsi panggilan balik ke properti
onopen
dari objek
connection
:
connection.onopen = () => {
Untuk menangani kesalahan, pengendali event
onerror
digunakan:
connection.onerror = error => { console.log(`WebSocket error: ${error}`) }
▍Mengirim data ke server
Setelah membuka koneksi WebSocket ke server, Anda dapat mengirim data ke sana. Ini dapat dilakukan, misalnya, dalam
onopen
:
connection.onopen = () => { connection.send('hey') }
▍Mendapatkan data dari server
Untuk menerima data yang dikirim menggunakan protokol WebSocket dari server, Anda dapat menetapkan
onmessage
onmessage, yang akan dipanggil ketika acara
message
diterima:
connection.onmessage = e => { console.log(e.data) }
▍ Implementasi server WebSocket di lingkungan Node.js
Untuk menerapkan server WebSocket di lingkungan Node.js, Anda dapat menggunakan pustaka
ws yang populer. Kami akan menggunakannya untuk pengembangan server, tetapi cocok untuk membuat klien, serta untuk mengatur interaksi antara dua server.
Instal pustaka ini dengan pertama-tama menginisialisasi proyek:
yarn init yarn add ws
Kode untuk server WebSocket yang perlu kita tulis cukup ringkas:
constWebSocket = require('ws') const wss = newWebSocket.Server({ port: 8080 }) wss.on('connection', ws => { ws.on('message', message => { console.log(`Received message => ${message}`) }) ws.send('ho!') })
Di sini kita membuat server baru yang mendengarkan pada port standar 8080 untuk protokol WebSocket dan menjelaskan panggilan balik, yang, ketika koneksi dibuat, mengirim pesan ke klien
ho!
dan mencetak ke konsol pesan yang diterima dari klien.
Ini adalah contoh kerja server WebSocket, dan
berikut adalah klien yang dapat berinteraksi dengannya.
Ringkasan
Hari ini kita berbicara tentang mekanisme jaringan yang didukung oleh platform Node.js, menggambar paralel dengan mekanisme serupa yang digunakan di browser. Topik kita berikutnya adalah menangani file.
Pembaca yang budiman! Apakah Anda menggunakan protokol WebSocket di aplikasi web Anda, sisi server yang dibuat menggunakan Node.js?