Apakah itu HTTP? Panduan untuk Pentadbir Pelayan
Ketahui cara HTTP berfungsi untuk pengurusan pelayan. Artikel ini merangkumi kaedah permintaan, kod status, konfigurasi header dalam log nginx, serta peranan penting TLS dan HTTP/3.
Apakah itu HTTP?
HTTP (hypertext transfer protocol) ialah set peraturan yang digunakan oleh klien dan pelayan web untuk meminta sesuatu dan menghantarnya semula. Klien menghantar permintaan: kaedah seperti GET, laluan seperti /pricing, versi protokol, senarai pengepala (headers), dan kadangkala badan (body). Pelayan menjawab dengan kod status seperti 200, diikuti oleh pengepalanya sendiri dan biasanya badan. Setiap paparan halaman dan setiap panggilan API (application programming interface) pada pelayan anda adalah pertukaran tersebut, yang diulang.
HTTP tidak menyimpan statusnya sendiri. Pelayan tidak mengingati apa yang anda minta sebentar tadi, jadi apa-apa yang berfungsi seperti memori, contohnya sesi log masuk, dibawa dalam pengepala pada setiap permintaan. Ciri tunggal itu menjelaskan banyak perkara seterusnya: caching sepenuhnya dipacu oleh pengepala, dan pengimbang beban (load balancer) boleh menghantar permintaan seterusnya anda ke backend yang berbeza tanpa merosakkan apa-apa.
Segala-galanya di bawah adalah rupa model tersebut dari sisi pelayan, dalam log akses anda dan dalam konfigurasi nginx anda.
Permintaan dan respons mentah, dengan anotasi
Berikut adalah permintaan HTTP/1.1 yang lengkap. Baris kosong menandakan tamatnya pengepala (headers), dan apa-apa selepas baris tersebut adalah badan (body). GET biasanya tidak mempunyai badan.
GET /pricing HTTP/1.1
Host: example.com
User-Agent: curl/8.5.0
Accept: */*
Accept-Encoding: gzipGETialah kaedah, yang menyatakan perkara yang anda mahu lakukan.GETmembaca,POSTmenghantar data,PUTmenggantikan,DELETEmembuang,HEADmeminta pengepala bagiGETtanpa badan./pricingialah laluan (path). Nama hos bukan sebahagian daripada baris permintaan, itulah sebabnya pengepala seterusnya wujud.HTTP/1.1ialah versi protokol yang digunakan oleh klien.Host: example.commenamakan tapak yang dikehendaki oleh klien. HTTP/1.1 memerlukannya, jadi nginx akan menjawab permintaan tanpa nama hos dengan400 Bad Request.- Selebihnya adalah keutamaan.
Accept-Encoding: gzipmenyatakan klien boleh menyahmampat, jadi pelayan dibenarkan untuk memampatkan badan.
Respons mempunyai bentuk yang sama dengan baris status di bahagian atas.
HTTP/1.1 200 OK
Date: Thu, 06 Aug 2026 09:12:44 GMT
Server: nginx
Content-Type: text/html; charset=utf-8
Content-Length: 5310
Cache-Control: public, max-age=300
<!doctype html>...200 OKialah kod status berserta frasa alasannya. Kod tersebut adalah perkara yang penting. Frasa itu hanyalah hiasan dan klien akan mengabaikannya.Content-Typememberitahu klien cara untuk mengendalikan bait yang menyusul.Content-Lengthialah saiz badan dalam bait, supaya klien tahu di mana badan berakhir. Apabila saiz tidak diketahui lebih awal, pelayan akan menghantarTransfer-Encoding: chunkedsebaliknya dan menandakan penghujung dengan ketulan (chunk) bersaiz sifar.Cache-Controlmemberitahu pelayar dan mana-mana cache di antaranya berapa lama mereka boleh menyimpan respons ini.- Baris kosong selepas pengepala memisahkannya daripada badan, dalam kedua-dua arah.
Nama pengepala tidak sensitif huruf besar/kecil, dan setiap baris berakhir dengan carriage return diikuti oleh line feed dan bukannya newline biasa. Anda tidak akan menaip ini secara manual, tetapi anda akan menemuinya dalam tangkapan paket (packet capture).
Untuk melihat pasangan sebenar, jalankan arahan ini terhadap tapak yang anda miliki:
curl -sS -o /dev/null -D - https://example.com/-D - menulis pengepala respons ke terminal anda dan -o /dev/null membuang badan respons. Gunakan ini berbanding curl -I, kerana -I menghantar permintaan HEAD. Pelayan aplikasi yang mengendalikan HEAD secara berbeza daripada GET, dan banyak yang berbuat demikian, akan menunjukkan kepada anda pengepala yang tidak pernah diterima oleh mana-mana pelayar. curl -v mencetak kedua-dua belah pihak, dengan baris permintaan ditandakan > dan baris respons ditandakan <.
Rupa baris permintaan dalam log akses nginx anda
nginx mengeluarkan format log combined, dan ini adalah definisinya:
log_format combined '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';Satu baris yang dihasilkan olehnya:
203.0.113.45 - - [06/Aug/2026:09:12:44 +0000] "GET /pricing HTTP/1.1" 200 5310 "https://example.com/" "Mozilla/5.0 (X11; Linux x86_64) Chrome/127.0.0.0 Safari/537.36"203.0.113.45ialah$remote_addr, alamat yang membuka sambungan TCP (transmission control protocol). Di sebalik proksi, ini adalah proksi, bukan pelawat.-yang pertama ialah pemegang tempat tetap. Yang kedua ialah$remote_user, yang diisi hanya apabila pengesahan asas HTTP digunakan."GET /pricing HTTP/1.1"ialah$request, baris permintaan yang disalin tepat seperti yang diterima.200ialah status yang dikembalikan oleh pelayan anda, bukan status yang dilihat oleh pelawat.5310ialah$body_bytes_sent, badan sahaja. Pengepala respons tidak dikira, jadi nombor ini sentiasa lebih kecil daripada bait yang sebenarnya dihantar.- Dua medan bertanda petikan terakhir ialah
RefererdanUser-Agent. Kedua-duanya datang daripada klien, jadi kedua-duanya boleh mengandungi apa sahaja.
Oleh kerana $request disalin secara verbatim, data sampah akan muncul secara verbatim. Klien yang bercakap TLS (transport layer security) ke port 80 teks biasa anda akan meninggalkan baris 400 yang medan permintaannya bermula dengan bait terlepas (escaped bytes) seperti "\x16\x03\x01\x02\x00\x01". \x16 ialah jenis rekod jabat tangan TLS, jadi bait tersebut adalah permulaan bagi ClientHello dan bukannya baris permintaan. Pelayan anda berkelakuan dengan betul. Sesuatu sedang menghalakan HTTPS ke port HTTP.
Tambahkan $server_protocol ke dalam format log anda juga. Ia mencetak HTTP/1.1, HTTP/2.0 atau HTTP/3.0, dan ia merupakan cara terpantas untuk membuktikan bahawa perubahan protokol benar-benar berkuat kuasa.
Makna kod status lazim apabila laman anda sendiri mengembalikannya
Digit pertama ialah kelas, dan kelas inilah yang perlu anda baca dahulu.
2xx bermaksud ia berjaya. 200 OK untuk bacaan biasa. 201 Created selepas POST yang mencipta sesuatu. 204 No Content untuk kejayaan tanpa data untuk dihantar balik, yang merupakan jawapan biasa bagi DELETE.
3xx bermaksud lihat di tempat lain. 301 adalah kekal dan pelayar menyimpannya dalam cache dengan kuat, kadangkala sehingga pengguna membersihkan profil mereka, jadi 301 yang menghala ke hostname yang salah adalah sukar untuk dibatalkan. Gunakan 302 semasa anda masih menguji redirect. 304 Not Modified adalah kejayaan, bukan ralat: klien menghantar If-None-Match yang membawa ETag (entity tag) yang anda masih kenali, jadi anda membalas dengan header tanpa body. Log yang penuh dengan 304 bermaksud caching berfungsi.
4xx bermaksud permintaan itu salah. 400 Bad Request ialah input yang tidak terbentuk dengan betul. 401 Unauthorized sebenarnya bermaksud tidak disahkan (unauthenticated), dan ia mesti membawa header WWW-Authenticate yang menamakan skema tersebut. 403 Forbidden bermaksud permintaan difahami tetapi tetap ditolak. 404 Not Found ialah path yang tidak wujud. 405 Method Not Allowed ialah path yang betul dengan method yang salah, iaitu apa yang dikembalikan oleh POST ke lokasi fail statik. 413 ialah body yang lebih besar daripada client_max_body_size nginx, yang secara lalai adalah 1 megabyte, dan log ralat mengesahkannya dengan client intended to send too large body.
403 pada fail statik hampir selalu berpunca daripada sistem fail dan bukannya peraturan HTTP. Baca /var/log/nginx/error.log sebelum menukar sebarang konfigurasi. open() "/srv/site/index.html" failed (13: Permission denied) bermaksud pengguna worker nginx tidak boleh membaca fail tersebut, selalunya kerana direktori induk tiada kebenaran execute untuk orang lain. directory index of "/srv/site/" is forbidden bermaksud path tersebut merujuk kepada direktori yang tiada fail indeks manakala autoindex dimatikan.
5xx bermaksud bahagian anda rosak. 500 ialah ralat yang tidak dikendalikan dalam aplikasi anda. 502 Bad Gateway bermaksud nginx tidak dapat memperoleh respons yang boleh digunakan daripada upstream, dan log ralat menamakan puncanya: connect() failed (111: Connection refused) while connecting to upstream bermaksud tiada apa-apa yang mendengar pada alamat dalam proxy_pass. 504 Gateway Timeout bermaksud upstream menerima sambungan tersebut kemudian tidak memberi respons dalam tempoh proxy_read_timeout, 60 saat secara lalai, yang direkodkan oleh log sebagai upstream timed out (110: Connection timed out) while reading response header from upstream. 503 Service Unavailable ialah penolakan sengaja. Ambil perhatian bahawa rate limiter nginx sendiri mengembalikan 503, kerana limit_req_status secara lalai ialah 503. Jika anda mencari 429 Too Many Requests dalam log anda dan menemui 503 sebaliknya, itulah sebabnya. Tetapkan limit_req_status 429; untuk mendapatkan kod yang tepat.
Header yang penting apabila anda menjalankan pelayan
Host menentukan tapak web. Satu alamat IP boleh melayani ratusan nama hos, dan nginx memadankan Host dengan server_name untuk menentukan blok server yang akan menjawab permintaan tersebut. Jika tiada padanan, nginx menggunakan pelayan lalai, iaitu blok pertama yang mendengar pada alamat dan port tersebut melainkan blok lain ditandakan sebagai default_server. Mendapatkan tapak web yang salah daripada virtual host baharu hampir selalu disebabkan oleh perkara ini: nama tidak sepadan, jadi permintaan tersebut jatuh ke pelayan lalai. Uji perkara ini tanpa menyentuh DNS:
curl -sS -o /dev/null -D - -H 'Host: app.example.com' http://127.0.0.1/User-Agent ialah penerangan kendiri yang ditulis oleh klien, dan ia merupakan teks bebas. Gunakannya sebagai petunjuk semasa membaca log. Jangan sekali-kali menggunakannya sebagai kawalan, kerana klien yang ingin menipu mengenainya akan melakukannya dengan mudah. Oleh itu, menyekat pengikis (scraper) melalui User-Agent hanya akan menapis klien yang beradab sahaja.
Content-Type menentukan cara bait ditafsirkan: application/json untuk permintaan API, text/html; charset=utf-8 untuk halaman. nginx memetakan sambungan fail kepada jenis menggunakan /etc/nginx/mime.types, dan nginx.conf yang dipakejkan menetapkan default_type application/octet-stream;. Jadi, fail dengan sambungan yang tidak dikenali oleh nginx akan ditawarkan sebagai muat turun dan bukannya dipaparkan. Gejala yang kelihatan ialah halaman dimuatkan tanpa penggayaan (styling) manakala konsol pelayar memaparkan Refused to apply style from ... because its MIME type ('text/plain') is not a supported stylesheet MIME type. MIME di sini bermaksud Multipurpose Internet Mail Extensions, iaitu skema penamaan yang menjadi asal usul rentetan jenis tersebut.
Cache-Control ialah cara anda mengawal setiap cache antara pelayan anda dan pembaca. public, max-age=31536000, immutable sesuai untuk aset yang nama failnya mengandungi hash kandungan, kerana nama fail berubah apabila kandungannya berubah. no-store sesuai untuk apa-apa yang khusus kepada pengguna, kerana cache kongsi yang menyimpan halaman pengguna yang telah log masuk akan memberikannya kepada orang seterusnya yang meminta URL yang sama. private ialah tetapan pertengahan: pelayar boleh menyimpannya, tetapi cache kongsi tidak boleh.
X-Forwarded-For wujud kerana proksi menyembunyikan pelawat. Sebaik sahaja permintaan melalui reverse proxy, $remote_addr menjadi alamat proksi tersebut, jadi log, geolokasi dan pengehadan kadar (rate limiting) anda hanya melihat satu klien. Proksi perlu menghantar alamat asal bersama-sama permintaan:
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;Pelayan penerima kemudiannya perlu diberitahu untuk mempercayainya, dan diberitahu dengan tepat siapa yang perlu dipercayai:
set_real_ip_from 10.0.0.0/8;
real_ip_header X-Forwarded-For;Senaraikan hanya julat yang anda kawal. X-Forwarded-For ialah teks biasa yang boleh dihantar oleh mana-mana klien, jadi set_real_ip_from 0.0.0.0/0; membolehkan pelawat memilih alamat yang anda log dan alamat yang dikira oleh pengehad kadar anda.
X-Forwarded-Proto menghalang kegagalan yang khusus dan sangat biasa berlaku. Proksi anda menamatkan TLS dan menghantar permintaan kepada aplikasi melalui HTTP biasa. Aplikasi melihat permintaan biasa, memutuskan bahawa pelawat sepatutnya berada di HTTPS, dan menjawab dengan 301 https://example.com/. Pelayar mengikutinya, proksi menamatkan TLS sekali lagi dan menghantar HTTP biasa sekali lagi, dan gelung ini berulang sehingga pelayar berputus asa dengan ERR_TOO_MANY_REDIRECTS. Menghantar X-Forwarded-Proto: https memberitahu aplikasi bahawa pelawat sudah berada di HTTPS, jadi ia berhenti melakukan redirect.
HTTP/1.1 lawan HTTP/2 lawan HTTP/3: apa yang berubah untuk anda
HTTP/1.1 berasaskan teks dan ia mengendalikan satu permintaan pada satu masa bagi setiap sambungan. Connection: keep-alive membolehkan permintaan seterusnya menggunakan semula sambungan TCP yang sama, yang menjimatkan kos penyediaan, namun respons masih kembali mengikut urutan permintaan dibuat. Satu respons yang perlahan akan menyekat segala-galanya yang beratur di belakangnya. Ini dipanggil head-of-line blocking, dan pelayar web mengatasinya dengan membuka beberapa sambungan ke hostname yang sama secara serentak.
HTTP/2 mengekalkan kaedah dan kod status yang sama, serta menukar pemformatan kepada binari. Banyak permintaan berkongsi satu sambungan sebagai aliran (stream) bebas, dan teks pengepala (header) yang berulang dimampatkan; ini penting kerana permintaan moden membawa banyak data pengepala. Sambungan tersebut masih menggunakan TCP, jadi satu paket yang hilang akan melambatkan setiap aliran pada sambungan itu sehingga penghantaran semula tiba. Masalah head-of-line blocking tidak hilang. Ia beralih daripada lapisan HTTP ke lapisan pengangkutan. Server push merupakan sebahagian daripada HTTP/2 tetapi tidak lagi digunakan secara praktikal, kerana Chrome telah membuang sokongannya pada tahun 2022.
HTTP/3 mengekalkan semantik yang sama dan menggantikan TCP dengan QUIC, iaitu protokol pengangkutan yang dibina di atas UDP (user datagram protocol). Aliran QUIC adalah bebas sepenuhnya, jadi paket yang hilang hanya akan melambatkan aliran yang berkaitan dengannya sahaja. TLS 1.3 dibina terus ke dalam jabat tangan (handshake) QUIC dan bukannya diletakkan sebagai lapisan tambahan, jadi sambungan baharu memerlukan kurang pusingan komunikasi (round trips). Dua kesan praktikal berlaku: port UDP 443 mesti dibuka dalam setiap firewall di sepanjang laluan, dan mana-mana rangkaian yang mengehadkan atau menyekat UDP akan memaksa klien kembali menggunakan HTTP/2.
Apa yang berubah untuk anda secara konkrit. Pelayar web tidak bermula dengan HTTP/3. Ia bersambung melalui HTTP/2 atau HTTP/1.1, melihat pengepala Alt-Svc: h3=":443"; ma=86400 pada respons, dan menggunakan HTTP/3 untuk sambungan seterusnya ke hos tersebut. Jadi, pengepala itu bukan hiasan pilihan. Ia adalah mekanisme penemuan. Dalam nginx, HTTP/2 menjadi direktifnya sendiri dalam versi 1.25.1 (http2 on; di dalam blok server, menggantikan parameter listen ... http2 yang lama), dan QUIC tiba dalam versi mainline 1.25.0, di mana tapak HTTP/3 memerlukan listen 443 quic reuseport; di samping listen 443 ssl; yang biasa.
Tahap kematangan proksi berbeza-beza dalam hal ini, dan anda perlu menyemaknya berdasarkan versi yang anda jalankan. Setakat Ogos 2026, Caddy menyediakan HTTP/3 secara lalai tanpa sebarang konfigurasi. nginx memerlukan pendengar quic yang eksplisit berserta pengepala Alt-Svc yang diterangkan di atas. Traefik mendayakannya bagi setiap entry point melalui pilihan http3 yang eksplisit. Jika anda menamatkan TLS di Traefik di hadapan beberapa aplikasi Docker, versi protokol yang diterima oleh pelawat anda ditentukan di situ, dan sambungan daripada proksi ke kontena anda biasanya adalah HTTP/1.1 biasa, tidak kira apa yang dirundingkan oleh pelayar web.
Sahkan, jangan sekadar mengandaikan. curl --http3 -sS -o /dev/null -D - https://example.com/ hanya berfungsi jika curl -V menyenaraikan HTTP3 dalam ciri-cirinya, dan kebanyakan binaan pengedaran tidak menyertakannya. Semakan yang boleh dipercayai adalah log anda sendiri: tambahkan $server_protocol pada format dan baca apa yang dirundingkan oleh pelayar web sebenar. Sebelum melakukan semua itu, pastikan UDP 443 benar-benar terbuka, kerana firewall yang hanya membenarkan TCP 443 akan menyebabkan HTTP/3 gagal secara senyap sementara tapak web terus berfungsi melalui HTTP/2. Mengetahui port mana yang terbuka dan mendengar pada pelayan Linux anda adalah perkara pertama yang perlu diperiksa.
HTTPS: HTTP ialah protokol, TLS ialah pembungkusnya
HTTPS bukanlah protokol yang berasingan. Ia adalah permintaan dan kod status yang sama yang dibawa di dalam sesi TLS. Port 80 membawanya dalam bentuk teks jelas (clear text) manakala port 443 membawanya dalam bentuk terenkripsi. Jabat tangan (handshake) TLS selesai terlebih dahulu, kemudian permintaan HTTP bergerak di dalam saluran terenkripsi tersebut. Urutan inilah sebabnya masalah sijil tidak pernah mempunyai kod status yang disertakan: kegagalan berlaku sebelum satu bait HTTP pun dihantar, jadi tiada respons untuk dinomborkan.
Satu perincian urutan adalah penting pada pelayan yang mengehoskan beberapa tapak web. Sijil dipilih menggunakan SNI (server name indication), iaitu medan dalam jabat tangan TLS yang membawa nama hos dalam bentuk teks jelas sebelum sebarang header HTTP wujud. Jadi, pelayan memilih sijil daripada SNI terlebih dahulu, kemudian memilih virtual host daripada header Host pada langkah kedua. Kedua-duanya adalah carian berasingan yang biasanya sepadan. Apabila ia tidak sepadan, pelayar akan memaparkan ketidakpadanan nama seperti NET::ERR_CERT_COMMON_NAME_INVALID dan tidak menghantar sebarang permintaan langsung, kerana sijil pelayan lalai anda ditawarkan untuk nama yang tidak dilindungi oleh sijil tersebut.
Untuk tapak awam, dapatkan sijil yang sah dan biarkan ia diperbaharui secara automatik. Certbot dengan Let's Encrypt pada nginx menulis laluan sijil ke dalam blok pelayan anda dan memasang pemasa pembaharuan untuk anda. Bagi nama hos yang tidak boleh disahkan oleh pihak berkuasa awam, seperti nama dalaman atau alamat IP kosong pada rangkaian anda sendiri, sijil yang ditandatangani sendiri (self-signed) pada Ubuntu adalah pilihan yang jujur, selagi anda menerima hakikat bahawa setiap klien perlu diberitahu untuk mempercayainya.
Apabila TLS berfungsi, hantar semua trafik pada port 80 ke port 443:
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}Tambahkan Strict-Transport-Security hanya apabila anda benar-benar pasti. Header add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always; memberitahu pelayar untuk menolak HTTP biasa bagi nama hos tersebut selama dua tahun, dan pelayar mematuhinya daripada cache mereka sendiri. Ini bermakna membuang header tersebut kemudian tidak akan membatalkan tindakan itu. Mulakan dengan max-age selama beberapa jam, sahkan setiap subdomain benar-benar menggunakan HTTPS, kemudian tingkatkan tempohnya.
FAQ
Apakah perbezaan antara HTTP dan HTTPS?
HTTPS ialah HTTP yang dihantar di dalam sesi TLS (transport layer security). Kaedah dan kod statusnya adalah sama. Perbezaannya ialah bait data disulitkan antara klien dan mana-mana titik yang menamatkan TLS, dan port lalai berubah daripada 80 kepada 443. Oleh kerana jabat tangan TLS selesai sebelum bait HTTP pertama dihantar, kegagalan sijil tidak akan menghasilkan kod status. Inilah sebabnya amaran sijil pelayar memaparkan nama ralat seperti NET::ERR_CERT_COMMON_NAME_INVALID dan bukannya nombor seperti 403.
Mengapa laman saya memaparkan 502 Bad Gateway?
502 daripada nginx bermaksud nginx tidak dapat memperoleh respons yang boleh digunakan daripada upstream yang diproksikannya, jadi permintaan pelawat adalah betul tetapi sesuatu di belakang nginx tidak berfungsi. Baca /var/log/nginx/error.log. connect() failed (111: Connection refused) while connecting to upstream bermaksud tiada apa-apa yang mendengar pada alamat dan port dalam proxy_pass, jadi pastikan aplikasi sedang berjalan dan terikat pada lokasi yang dijangkakan. no live upstreams while connecting to upstream bermaksud setiap pelayan dalam blok upstream telah ditandakan sebagai tidak aktif selepas kegagalan berulang. Bandingkan dengan 504 Gateway Timeout, yang bermaksud upstream menerima sambungan tersebut tetapi gagal menjawab dalam tempoh proxy_read_timeout.
Mengapa log akses saya menunjukkan alamat IP yang sama untuk setiap pelawat?
Kerana $remote_addr merekodkan alamat yang membuka sambungan TCP, dan di sebalik reverse proxy atau rangkaian penghantaran kandungan (CDN), alamat tersebut ialah proksi itu sendiri. Alamat pelawat tiba dalam header X-Forwarded-For sebaliknya. Tetapkan proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; pada proksi, kemudian pada nginx penerima, tetapkan set_real_ip_from kepada julat alamat proksi dan real_ip_header X-Forwarded-For;. Senaraikan hanya julat yang anda kawal, kerana header tersebut hanyalah teks yang boleh dihantar oleh mana-mana klien. Mempercayainya daripada seluruh internet membolehkan pelawat memilih alamat yang anda log dan alamat yang anda hadkan kadarnya (rate limit).
Adakah saya perlu menghidupkan HTTP/2 atau HTTP/3?
HTTP/2 berbaloi untuk dihidupkan kerana ia hanya memerlukan satu arahan pada tapak yang sudah mempunyai TLS, dan ia membuang had permintaan setiap sambungan yang menyebabkan halaman dengan banyak fail kecil menjadi perlahan. HTTP/3 memberikan peningkatan yang lebih kecil dan kurang pasti, serta memerlukan port UDP 443 dibuka dan binaan proksi dengan sokongan QUIC. Ingat bahawa pelayar hanya bertukar kepada HTTP/3 selepas ia melihat header Alt-Svc pada respons terdahulu, jadi tanpa header tersebut, tiada apa yang berubah tidak kira apa yang dinyatakan oleh baris listen anda. Tambahkan $server_protocol pada format log anda dan ukur apa yang sebenarnya dirundingkan oleh pelawat sebelum meluangkan masa untuknya.
Apakah maksud 403 Forbidden apabila fail tersebut wujud?
Pada tapak statik, 403 biasanya merupakan isu kebenaran sistem fail dan bukannya peraturan HTTP. open() ... failed (13: Permission denied) dalam /var/log/nginx/error.log bermaksud pengguna pekerja nginx tidak boleh membaca fail tersebut, selalunya kerana direktori induk kekurangan kebenaran laksana (execute permission) untuk orang lain, bukannya kerana mod fail itu sendiri yang salah. directory index of ... is forbidden bermaksud permintaan tersebut merujuk kepada direktori tanpa fail indeks manakala autoindex dimatikan. Peraturan deny yang eksplisit dalam blok location yang sepadan juga akan mengembalikan 403, jadi baca blok tersebut apabila log ralat tidak menyatakan apa-apa.