Memahami CORS: Kenapa Ia Ada

Penjelasan CORS untuk pemula: apa itu same-origin policy, kenapa browser memblokir pembacaan respons lintas origin, dan bagaimana server memberi izin lewat header Access-Control serta preflight.

Diterbitkan 15 September 20268 menit bacaOleh ACY Partner Indonesia
Sampul Memahami CORS dengan chip kode origin-A ke origin-B
300 × 250Slot Iklan TersediaPasang iklan Anda di sini

Kalau kamu pernah menulis kode frontend, kemungkinan besar kamu sudah berkenalan dengan error CORS yang bikin pusing itu. Kamu menyiapkan sebuah fetch ke API, klik refresh, buka konsol browser, dan di situlah ia muncul dengan teks merah menyala: ada keterangan soal “blocked by CORS policy”. Permintaannya kelihatan baik-baik saja. API-nya jalan kalau dibuka di tab baru. Lalu kenapa browser menolak menyerahkan respons itu ke kamu?

Jawaban singkatnya: CORS bukan bug, dan browser juga tidak sedang rewel. Ia adalah mekanisme keamanan yang sedang menjalankan tugasnya dengan benar. Tapi untuk benar-benar paham, kita perlu mundur sebentar dan membahas satu aturan yang jadi fondasi seluruh web: same-origin policy. Begitu bagian ini nyangkut di kepala, CORS tidak lagi terasa seperti penghalang acak, melainkan seperti sebuah pintu berkunci yang memang masuk akal.

Apa arti “origin” sebenarnya

Sebelum apa pun, mari kita kunci dulu kata origin, karena seluruh pembahasan ini bergantung padanya. Origin adalah gabungan dari tiga hal dalam sebuah URL:

  • skema (seperti http atau https),
  • host (seperti blog.acy-partner.com),
  • dan port (seperti 443 atau 3000).

Kalau ketiganya cocok antara dua URL, keduanya berada di origin yang sama. Kalau ada satu saja yang berbeda, keduanya origin yang berbeda. Bagian terakhir inilah yang sering mengecoh pemula, jadi mari lihat tabel konkret berikut:

URL A URL B Origin sama? Alasan
https://acy-partner.com/page https://acy-partner.com/other Ya Skema, host, port semua cocok
https://acy-partner.com http://acy-partner.com Tidak Skema beda (https vs http)
https://acy-partner.com https://blog.acy-partner.com Tidak Host beda (subdomain ikut dihitung)
https://acy-partner.com https://acy-partner.com:8080 Tidak Port beda

Perhatikan, path (/page vs /other) tidak memengaruhi origin. Yang penting hanya skema, host, dan port. Dan benar, subdomain seperti blog. diperlakukan sebagai origin yang sama sekali terpisah dari domain utamanya.

Same-origin policy, dijelaskan sederhana

Same-origin policy adalah aturan yang sudah tertanam di setiap browser. Dalam satu kalimat: sebuah halaman web boleh mengirim permintaan ke origin lain, tapi secara default ia tidak boleh membaca respons dari origin tersebut.

Perbedaan antara mengirim dan membaca inilah inti dari seluruh topik ini, jadi mari kita pelan-pelan di sini. Browser tidak masalah membiarkan satu situs memicu permintaan ke situs lain. Itu hal yang normal dan memang perlu, karena gambar, skrip, font, dan stylesheet terus-menerus dimuat lintas origin. Yang dijaga ketat oleh browser adalah apakah JavaScript di halaman tersebut boleh melihat data respons yang kembali.

Kenapa seketat itu? Bayangkan kamu sedang login ke akun bank di satu tab. Di tab lain, kamu membuka situs yang mencurigakan. Tanpa same-origin policy, JavaScript di situs mencurigakan itu bisa diam-diam membuat permintaan ke API bank kamu. Karena kamu sedang login, browser otomatis akan menyertakan cookie sesi kamu, dan bank akan merespons dengan detail rekening kamu. Kalau halaman mencurigakan tadi bisa membaca respons itu, ia bisa mencuri semuanya. Same-origin policy adalah tembok yang menghalangi halaman tersebut membaca apa yang kembali, walaupun secara teknis permintaannya tetap terkirim.

Mengirim versus membaca

Browser biasanya tetap membiarkan permintaan lintas origin keluar. Yang ia blokir adalah halamanmu membaca responsnya. Itulah kenapa panggilan API-mu bisa sampai ke server dan bahkan menjalankan kode server, tapi JavaScript-mu tetap hanya menerima error.

Lalu di mana CORS masuk?

Same-origin policy adalah default yang masuk akal, tapi terlalu ketat untuk web modern. Setiap saat, aplikasi yang sah perlu berkomunikasi lintas origin. Frontend yang di-hosting di https://acy-partner.com mungkin perlu memanggil API di https://api.acy-partner.com. Aplikasi single-page di satu domain mungkin menarik data dari layanan publik di domain lain. Memblokir semua itu akan membuat banyak arsitektur yang berguna jadi mustahil.

CORS — Cross-Origin Resource Sharing — adalah cara resmi untuk melonggarkan same-origin policy secara terkendali. Ini ide kuncinya, dan layak diingat baik-baik:

CORS adalah server yang memberi izin. Server memberi tahu browser, “Saya tidak keberatan origin lain ini membaca respons saya.” Browser baru melonggarkan aturannya kalau server secara eksplisit menyatakannya.

Ini pergeseran cara berpikir yang penting bagi pemula. CORS bukan sesuatu yang kamu atur di frontend untuk “mengizinkan” permintaanmu. Izinnya ada di server yang memiliki datanya. Browser adalah penegaknya; server adalah pihak yang memberi izin.

Header yang menjalankan tugasnya

Cara server memberi izin ini adalah lewat sebuah header respons HTTP bernama Access-Control-Allow-Origin. Ketika browser menerima respons lintas origin, ia mencari header ini untuk memutuskan apakah halaman boleh membaca isinya.

Pertukaran sederhana yang berhasil terlihat seperti ini:

GET /data HTTP/1.1
Host: api.acy-partner.com
Origin: https://acy-partner.com
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://acy-partner.com
Content-Type: application/json

{ "message": "Halo dari API" }

Ada dua hal yang terjadi. Browser, karena tahu ini panggilan lintas origin, otomatis menyertakan header Origin yang menyebutkan dari mana permintaan itu berasal. Server merespons dengan Access-Control-Allow-Origin yang menggemakan origin yang sama, dan ini memberi tahu browser, “ya, origin ini boleh membacaku.” Browser lalu menyerahkan JSON itu ke JavaScript kamu.

Kalau header itu tidak ada, atau menyebut origin yang berbeda, browser menolak menampilkan responsnya — dan itulah error CORS yang kamu lihat di konsol. Responsnya sering kali sebenarnya sudah sampai; browser hanya mencabiknya sebelum kodemu sempat menyentuhnya.

Nilai Access-Control-Allow-Origin Efek
https://acy-partner.com Hanya origin persis itu yang boleh membaca respons
* (wildcard) Origin mana pun boleh membaca — dipakai untuk data yang benar-benar publik
(header tidak ada) Tidak ada pembacaan lintas origin yang diizinkan; browser memblokir

Wildcard punya batas

Access-Control-Allow-Origin: * membuat origin mana pun bisa membaca respons, tapi ia tidak bisa digabung dengan permintaan ber-kredensial (yang mengirim cookie). Kalau permintaanmu perlu mengirim cookie, server harus menyebut origin spesifik dan juga mengirim Access-Control-Allow-Credentials: true. Wildcard plus kredensial ditolak browser secara sengaja.

Preflight: ketukan sopan sebelum pintu dibuka

Sampai sini kita membahas permintaan sederhana. Tapi beberapa permintaan dianggap cukup berisiko sampai-sampai browser tidak langsung mengirimnya. Sebagai gantinya, ia mengirim sebuah permintaan kecil “boleh tidak?” lebih dulu. Ini disebut preflight, dan ia memakai metode HTTP OPTIONS.

Sebuah permintaan memicu preflight ketika ia bukan permintaan “sederhana” — misalnya saat memakai metode seperti PUT atau DELETE, atau saat mengirim header seperti Content-Type: application/json atau header Authorization kustom. Logikanya bersifat melindungi: permintaan semacam itu bisa mengubah data di server, jadi browser memeriksa izinnya sebelum melakukan apa pun yang nyata.

Berikut alur lengkap untuk permintaan yang butuh preflight:

  Browser (origin-A)                       Server (origin-B)
        |                                         |
        |  1. OPTIONS /orders  (preflight)        |
        |     Origin: origin-A                    |
        |     Access-Control-Request-Method: PUT  |
        | --------------------------------------> |
        |                                         |
        |  2. 204 No Content                      |
        |     Access-Control-Allow-Origin: A      |
        |     Access-Control-Allow-Methods: PUT   |
        | <-------------------------------------- |
        |                                         |
        |  3. PUT /orders yang sebenarnya         |
        | --------------------------------------> |
        |                                         |
        |  4. 200 OK + Access-Control-Allow-Origin|
        | <-------------------------------------- |

Di langkah 1 browser bertanya, tanpa mengirim payload aslinya, “Saya mau membuat permintaan PUT dari origin-A dengan header-header ini — apakah diizinkan?” Di langkah 2 server menjawab origin, metode, dan header apa saja yang diizinkannya. Hanya kalau jawabannya mencakup apa yang dibutuhkan permintaan asli, barulah browser lanjut ke langkah 3 dan mengirim PUT yang sebenarnya. Kalau preflight ditolak, permintaan aslinya bahkan tidak pernah keluar dari browser.

Header-header yang terlibat dalam respons preflight layak dijadikan rujukan singkat:

Header respons Arti
Access-Control-Allow-Origin Origin mana yang diizinkan
Access-Control-Allow-Methods Metode HTTP apa yang diizinkan (mis. GET, POST, PUT)
Access-Control-Allow-Headers Header permintaan apa yang diizinkan (mis. Content-Type, Authorization)
Access-Control-Max-Age Berapa lama browser boleh menyimpan hasil preflight ini, dalam detik

Yang terakhir, Access-Control-Max-Age, adalah optimasi yang manis: ia membuat browser bisa mengingat jawaban preflight untuk sementara, sehingga tidak perlu bertanya sebelum setiap permintaan.

Kenapa pemula terus-menerus kena error CORS

Sekarang setelah semua kepingnya tersusun, pengalaman klasik pemula jadi masuk akal. Kamu membangun frontend di http://localhost:3000 dan API di http://localhost:5000. Port yang berbeda berarti origin yang berbeda, jadi browser menegakkan CORS. API kamu tidak pernah mengeset Access-Control-Allow-Origin, jadi browser memblokir pembacaannya, dan kamu pun kena error — padahal server-nya sendiri sudah merespons dengan sempurna.

Beberapa hal yang membingungkan orang di tahap ini:

  • Error-nya adalah ulah browser, bukan server. Alat seperti curl atau Postman tidak menegakkan same-origin policy, makanya API-mu “jalan” di sana tapi gagal di browser. Alat-alat itu bukan browser, jadi tidak ada halaman yang perlu dilindungi.
  • Kamu tidak bisa memperbaiki CORS murni dari frontend. Izinnya harus datang dari header respons server. Sebanyak apa pun kamu mengutak-atik opsi fetch, browser tidak akan memercayai origin yang tidak pernah disetujui server.
  • Preflight yang gagal terlihat seperti permintaan yang gagal. Kalau panggilan OPTIONS-mu ditolak, permintaan asli tidak pernah berjalan, dan konsol mungkin menunjuk ke panggilan utama, menyembunyikan fakta bahwa preflight-lah biang keladinya.

Solusinya ada di server

Saat kena error CORS, tanyakan: “Halaman saya ada di origin apa, dan apakah respons server menyertakan Access-Control-Allow-Origin yang cocok dengannya?” Solusinya hampir selalu mengonfigurasi server (atau middleware CORS-nya) agar mengizinkan origin frontend kamu — bukan mengubah browser atau frontend.

Rangkuman singkat

Mari kita rangkai semuanya. Same-origin policy adalah aturan keamanan browser: sebuah halaman boleh mengirim permintaan ke origin lain tapi, secara default, tidak boleh membaca responsnya. Origin adalah trio skema, host, dan port — ubah salah satu saja, kamu sudah punya origin baru. Aturan ini ada untuk menghalangi halaman berbahaya diam-diam membaca data pribadimu di situs tempat kamu sedang login.

CORS adalah cara terkendali untuk melonggarkan aturan itu. Cara kerjanya lewat server yang memberi izin: ia mengirim header Access-Control-Allow-Origin (beserta kawan-kawannya) yang memberi tahu browser origin mana yang boleh membaca responsnya. Untuk permintaan yang lebih berisiko, browser lebih dulu mengirim permintaan preflight OPTIONS untuk memastikan izin sebelum mengirim yang sebenarnya. Error CORS yang terkenal itu sebenarnya hanya berarti browser tidak menemukan izin yang bisa ia percaya, jadi ia menolak menampilkan respons ke kodemu.

Begitu kamu benar-benar paham bahwa CORS adalah izin yang diberikan server dan ditegakkan browser, semuanya berubah dari tembok yang menjengkelkan menjadi sebuah kontrak yang jelas dan masuk akal. Dari sini, langkah lanjutan yang wajar adalah menengok lebih dekat bagaimana cookie dan header Access-Control-Allow-Credentials bekerja bersama, karena permintaan lintas origin ber-kredensial punya aturannya sendiri yang harus cermat — dan di situlah banyak teka-teki CORS dunia nyata yang lebih rumit bersembunyi.

Tag:corshttpkeamanansame-originbrowserweb-fundamentals
728 × 90Slot Iklan TersediaPasang iklan Anda di sini

Artikel Terkait

Lihat Semua Artikel

Artikel yang Mungkin Kamu Suka

Ilustrasi DOM sebagai pohon dari node HTML
Dasar-Dasar Web / Browser

Apa Itu DOM?

Penjelasan DOM untuk pemula: pohon HTML yang hidup di memori browser. Pahami apa itu DOM, bagaimana pohonnya dibentuk, dan kenapa ia begitu penting.

15 Sep 20267 menit baca
Ilustrasi berjudul Apa Itu Web Browser dengan code chip fetch ke render
Dasar-Dasar Web / Browser

Apa Itu Web Browser?

Penjelasan sederhana soal web browser: program yang mengambil berkas dari web lalu menyusunnya menjadi halaman yang kamu lihat, satu tab dan satu klik setiap saat.

15 Sep 20268 menit baca
Ilustrasi engine browser menjalankan skrip lewat event loop
Dasar-Dasar Web / Browser

Cara Browser Menangani JavaScript

Penjelasan ramah pemula soal bagaimana browser membaca, mengubah, dan menjalankan JavaScript, kenapa hanya punya satu jalur utama, dan bagaimana cara memuat skrip memengaruhi tampilan halaman.

15 Sep 20268 menit baca
Sampul biru gelap bertuliskan Cara Kerja Browser dengan chip kode parse ke layout ke paint
Dasar-Dasar Web / Browser

Cara Kerja Browser: Gambaran Umum

Penjelasan ramah pemula tentang apa yang dilakukan browser dari kamu mengetik URL sampai halaman muncul: jaringan, parsing, render tree, layout, paint, compositing, dan mesin JavaScript.

15 Sep 20268 menit baca
Sampul Critical Rendering Path dengan chip timer first paint
Dasar-Dasar Web / Browser

Critical Rendering Path

Ikuti langkah persis yang dilakukan browser untuk mengubah HTML, CSS, dan JavaScript menjadi piksel pertama yang terlihat, dan pahami kenapa posisi CSS dan JS menentukan secepat apa halaman muncul.

15 Sep 20267 menit baca
Sampul Dasar Keamanan Browser dengan chip kode berlambang perisai same-origin
Dasar-Dasar Web / Browser

Dasar Keamanan Browser: Cara Browser Diam-Diam Melindungimu

Panduan ramah untuk pemula tentang cara browser menjaga keamananmu: same-origin policy, sandboxing antar-tab, gembok HTTPS, mixed content, dan pengantar lembut soal kenapa input bisa berbahaya.

15 Sep 202610 menit baca