CORS adalah singkatan dari Cross-Origin Resource Sharing (berbagi sumber daya dari berbagai macam sumber). Sebuah spesifikasi yang memungkinkan akses API/Web Service secara terbuka melebihi batas-batas domain, misalnya mengakses API domain example.org dari domain sample.com.
Browser (peramban) menerapkan same-origin policy, yaitu kebijakan yang memperbolehkan akses dari asal yang sama, selain itu tidak diperbolehkan.
Origin | Host | Hasil | Alasan |
---|---|---|---|
https://www.s.org | https://www.s.org/dir/index.html | v | |
https://www.s.org | https://username:password@www.s.org | v | |
https://www.s.org | https://www.s.org:81/dir/index.html | x | port berbeda |
https://www.s.org | http://www.s.org/dir/index.html | x | skema berbeda |
https://www.s.org | https://service.s.org/dir/index.html | x | host berbeda |
https://www.s.org | https://s.org/dir/index.html | x | host berbeda |
https://www.s.org | https://v2.www.s.org/dir/index.html | x | host berbeda |
https://www.s.org | https://www.s.org:80/dir/index.html | ? | tergantung browser |
Daftar Isi
Penanganan error pada CORS, OPTIONS dan Header
Akses API atau Web Service ke skema, host dan port yang berbeda (CORS) menggunakan AJAX akan menimbulkan error karena browser menerapkan same origin policy untuk meningkatkan keamanan. Solusinya adalah melakukan pengaturan pada server agar mengijinkan CORS.
— Error CORS, OPTIONS dan Header pada Jquery / Javascript / Ajax dan Apache2
Pengaturan Apache2
#alamat server API: https://service.example.org
<VirtualHost _default_:443>
#...
<Directory "/var/www/html/service">
#hindari menggunakan * karena mungkin menimbulkan perilaku yang tidak sesuai harapan
Header always set Access-Control-Allow-Credentials "true"
#lihat di request header bagian Origin, tidak disarankan menggunakan *
Header always set Access-Control-Allow-Origin "https://www.example.org"
#jika lebih dari 1
#SetEnvIf Origin "^(https:\/\/www\.example\.org|https:\/\/www\.example\.com)$" REQUEST_ORIGIN=$0
#Header always set Access-Control-Allow-Origin %{REQUEST_ORIGIN}e env=REQUEST_ORIGIN
#dapat ditambah dengan metode lain
Header always set Access-Control-Allow-Methods "OPTIONS, GET, POST"
Header always set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization"
Header always set Access-Control-Expose-Headers "Content-Security-Policy, Location"
Header always set Vary "Origin"
#...
#tambahkan ini juga di .htaccess
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
#...
</Directory>
#...
</VirtualHost>
Pengaturan .htaccess
RewriteEngine On
#...
#tambahkan ini juga di .htaccess
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
#...
Pemanggilan API/Web Service Menggunakan JQuery
//alamat website: https://www.example.org
$.ajax({
url: "https://service.example.org/api/get_data",
dataType:'text/html', //tipe lain memungkinkan terjadi preflight (Metode OPTIONS)
method: 'GET',
success: function(data) {},
error: function() {}
});
Penjelasan
Apabila permintaan ditambah dengan OPTIONS, padahal permintaan awalnya GET atau POST, maka hal tersebut menandakan bahwa browser mengirimkan permintaan preflight terlebih dahulu. Lakukan hal berikut untuk mengantisipasi preflight
- Gunakan Content Type berupa text/html (
dataType:'text/html'
) pada JQuery / Ajax / Javascript untuk menghindari preflight - Tidak menggunakan header yang tidak standar pada JQuery / Ajax / Javascript untuk menghindari preflight
- Tambahkan pada pengaturan server di Apache2 dan htaccess agar OPTIONS success, bukan redirect
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L] - Gunakan
Header always set
pada pengaturan header di Apache2, bukan hanyaHeader set
Aktifkan CORS di server Apache2 dengan
- Jika API bersifat publik dan siapa saja boleh mengakses, maka gunakan
Header always set Access-Control-Allow-Origin "*"
- Ingat, origin harus benar-benar sama skema, host dan portnya. Origin dapat dilihat pada header request.
Jika API hanya boleh diakses dari sumber yang disetujui, maka gunakanHeader always set Access-Control-Allow-Origin "https://www.example.org"
Header always set Vary "Origin"
- Jangan gunakan * untuk header yang diijinkan, tetapi disebutkan secara eksplisit. Setidak-tidaknya ijinkan header berikut
Header always set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization"
Header always set Access-Control-Expose-Headers "Content-Security-Policy, Location"
- Jangan gunakan * untuk metode yang diijinkan, tetapi disebutkan secara eksplisit. Setidak-tidaknya ijinkan metode berikut
Header always set Access-Control-Allow-Methods "OPTIONS, GET, POST"
- Apabila terdapat otentikasi, maka bolehkan kredensial sebagai berikut
Header always set Access-Control-Allow-Credentials "true"
Demikian, semoga bermanfaat. [bst]
Sumber:
- https://stackoverflow.com/questions/42558221/how-to-cors-enable-apache-web-server-including-preflight-and-custom-headers
- https://stackoverflow.com/questions/69478852/firefox-cors-missing-allow-header
- https://stackoverflow.com/questions/41526654/javascript-jquery-send-custom-header-in-options-preflight-api