Saya mengerjakan proyek pribadi saya ini hanya untuk bersenang-senang di mana saya ingin membaca file xml yang terletak di http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml dan mengurai xml dan gunakan untuk mengonversi nilai antar mata uang.
Sejauh ini saya telah menemukan kode di bawah ini yang cukup mendasar untuk membaca xml tetapi saya mendapatkan kesalahan berikut.
XMLHttpRequest tidak dapat memuat ****. Tidak ada header 'Access-Control-Allow-Origin' yang ada di resource yang diminta. Oleh karena itu, asal ' http://run.jsbin.com ' tidak diizinkan untuk diakses.
$(document).ready(
function() {
$.ajax({
type: 'GET',
url: 'http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml',
dataType: 'xml',
success: function(xml){
alert('aaa');
}
});
}
);
Saya tidak melihat ada yang salah dengan kode saya, jadi saya berharap seseorang dapat menunjukkan kesalahan yang saya lakukan dengan kode saya dan bagaimana saya bisa memperbaikinya.
sumber
Jawaban:
Anda tidak akan dapat melakukan panggilan ajax ke
http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml
dari file yang diterapkan dihttp://run.jsbin.com
karena kebijakan asal yang sama .Karena halaman sumber (alias asal ) dan URL target berada di domain yang berbeda (
run.jsbin.com
danwww.ecb.europa.eu
), kode Anda sebenarnya mencoba membuat permintaan Cross-domain (CORS) , bukan hal biasaGET
.Singkatnya, kebijakan yang sama-asal mengatakan bahwa browser hanya mengizinkan panggilan ajax ke layanan di domain yang sama pada halaman HTML.
Contoh:
Halaman di
http://www.example.com/myPage.html
hanya dapat secara langsung meminta layanan yang ada dihttp://www.example.com
, sepertihttp://www.example.com/api/myService
. Jika layanan dihosting di domain lain (misalnyahttp://www.ok.com/api/myService
), browser tidak akan melakukan panggilan secara langsung (seperti yang Anda harapkan). Sebaliknya, ia akan mencoba membuat permintaan CORS.Singkatnya, untuk melakukan permintaan (CORS) * di berbagai domain, browser Anda:
Origin
header dalam permintaan asli (dengan domain halaman sebagai nilai) dan melakukannya seperti biasa; laluAccess-Control-Allow-Origin
adalah salah satu dari mereka ) yang memungkinkan CORS meminta, browse akan menyelesaikan panggilan (hampir ** persis dengan cara yang akan jika halaman HTML berada di domain yang sama).* Di atas menggambarkan langkah-langkah dalam permintaan sederhana , seperti permintaan biasa
GET
tanpa header mewah. Jika permintaan tidak sederhana (sepertiPOST
denganapplication/json
sebagai tipe konten), browser akan menahannya sebentar, dan, sebelum memenuhinya, terlebih dahulu akan mengirimOPTIONS
permintaan ke URL target. Seperti di atas, ini hanya akan berlanjut jika tanggapan atasOPTIONS
permintaan ini berisi header CORS. IniOPTIONS
panggilan dikenal sebagai preflight permintaan.** Saya katakan hampir karena ada perbedaan lain antara panggilan biasa dan panggilan CORS. Yang penting adalah bahwa beberapa header, meskipun ada dalam respons, tidak akan diambil oleh browser jika tidak disertakan dalam
Access-Control-Expose-Headers
header.Bagaimana memperbaikinya?
Apakah itu hanya salah ketik? Terkadang kode JavaScript hanya memiliki kesalahan ketik di domain target. Sudahkah kamu periksa? Jika halaman di
www.example.com
itu hanya akan membuat panggilan biasa kewww.example.com
! URL lain, sepertiapi.example.com
atau bahkanexample.com
atauwww.example.com:8080
dianggap domain berbeda oleh browser! Ya, jika porta berbeda, maka itu adalah domain yang berbeda!Tambahkan header. Cara termudah untuk mengaktifkan CORS adalah dengan menambahkan header (sebagai
Access-Control-Allow-Origin
) yang diperlukan ke respons server. (Setiap server / bahasa memiliki cara untuk melakukan itu - periksa beberapa solusi di sini .)Pilihan terakhir: Jika Anda tidak memiliki akses sisi server ke layanan, Anda juga dapat mencerminkannya (melalui alat seperti proxy terbalik ), dan menyertakan semua tajuk yang diperlukan di sana.
sumber
Access-Control-Allow-Origin
URL itu header sama sekali tidak penting - browser akan membuka URL seperti biasa. Kebijakan yang sama-asal (dan persyaratan untukAccess-Control-Allow-Origin
header) hanya berlaku untuk panggilan Ajax.Ada semacam cara hack-tastic untuk melakukannya jika Anda mengaktifkan php di server Anda. Ubah baris ini:
url: 'http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml',
ke baris ini:
url: '/path/to/phpscript.php',
dan kemudian di skrip php (jika Anda memiliki izin untuk menggunakan fungsi file_get_contents ()):
<?php header('Content-type: application/xml'); echo file_get_contents("http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml"); ?>
Php sepertinya tidak keberatan jika url itu berasal dari sumber yang berbeda. Seperti yang saya katakan, ini adalah jawaban yang meretas, dan saya yakin ada yang salah dengan itu, tetapi berhasil untuk saya.
Edit: Jika Anda ingin meng-cache hasilnya di php, berikut file php yang akan Anda gunakan:
<?php $cacheName = 'somefile.xml.cache'; // generate the cache version if it doesn't exist or it's too old! $ageInSeconds = 3600; // one hour if(!file_exists($cacheName) || filemtime($cacheName) > time() + $ageInSeconds) { $contents = file_get_contents('http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml'); file_put_contents($cacheName, $contents); } $xml = simplexml_load_file($cacheName); header('Content-type: application/xml'); echo $xml; ?>
Kode cache diambil dari sini .
sumber
file_get_contents
panggilan jika file XML terbaru memiliki tanggal yang memadai. Juga, jangan lupa header Jenis Konten Anda :-)