Я работаю над своим личным проектом просто для удовольствия, где я хочу прочитать файл xml, расположенный по адресу http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml, и проанализировать xml и используйте его для преобразования значений между валютами.
До сих пор я придумал приведенный ниже код, который является довольно простым для чтения xml, но я получаю следующую ошибку.
XMLHttpRequest не может загрузить ****. На запрошенном ресурсе нет заголовка Access-Control-Allow-Origin. Следовательно, к источнику " http://run.jsbin.com " доступ запрещен.
$(document).ready(
function() {
$.ajax({
type: 'GET',
url: 'http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml',
dataType: 'xml',
success: function(xml){
alert('aaa');
}
});
}
);
Я не вижу ничего плохого в моем коде, поэтому я надеюсь, что кто-то может указать, что я делаю не так с моим кодом и как я могу это исправить.
javascript
jquery
ajax
xml-parsing
cors
Bazinga777
источник
источник
Ответы:
Вы не сможете выполнить ajax-вызов
http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml
из файла, развернутого в,http://run.jsbin.com
из -за политики того же происхождения .Поскольку исходная страница (также известная как origin ) и целевой URL-адрес находятся в разных доменах (
run.jsbin.com
иwww.ecb.europa.eu
), ваш код на самом деле пытается сделать междоменный (CORS) запрос, а не обычныйGET
.Короче говоря, политика одного и того же происхождения гласит, что браузеры должны разрешать вызовы ajax только к службам в том же домене HTML-страницы.
Пример:
Страница по адресу
http://www.example.com/myPage.html
может напрямую запрашивать только те услуги, которые находятся по адресуhttp://www.example.com
, напримерhttp://www.example.com/api/myService
. Если служба размещена в другом домене (скажемhttp://www.ok.com/api/myService
), браузер не будет выполнять вызов напрямую (как и следовало ожидать). Вместо этого он попытается сделать запрос CORS.Короче говоря, для выполнения запроса (CORS) * в разных доменах ваш браузер:
Origin
заголовок в исходный запрос (с доменом страницы в качестве значения) и выполнит его как обычно; а потомAccess-Control-Allow-Origin
это один из них ) позволяя CORS запрос, просматривает завершит вызов (почти ** именно так , как это было бы , если страница HTML была в том же домене).* Выше показаны шаги в простом запросе, например в обычном запросе
GET
без дополнительных заголовков. Если запрос не является простым (например,POST
сapplication/json
типом содержимого as), браузер задержит его на мгновение и, прежде чем выполнить его, сначала отправитOPTIONS
запрос на целевой URL. Как и выше, он будет продолжаться только в том случае, если ответ на этотOPTIONS
запрос содержит заголовки CORS. ЭтотOPTIONS
вызов называется предполетным запросом.** Я говорю почти потому, что есть другие различия между обычными вызовами и вызовами CORS. Важным является то, что некоторые заголовки, даже если они присутствуют в ответе, не будут приняты браузером, если они не включены в
Access-Control-Expose-Headers
заголовок.Как это исправить?
Это просто опечатка? Иногда в коде JavaScript есть просто опечатка в целевом домене. Вы проверили? Если страница находится на
www.example.com
ней, будут совершаться только регулярные звонки по адресуwww.example.com
! Другие URL-адреса, такие какapi.example.com
или дажеexample.com
илиwww.example.com:8080
считаются браузером другими доменами! Да, если порт другой, то это другой домен!Добавьте заголовки. Самый простой способ включить CORS - это добавить необходимые заголовки (as
Access-Control-Allow-Origin
) к ответам сервера. (У каждого сервера / языка есть способ сделать это - проверьте некоторые решения здесь .)В крайнем случае : если у вас нет доступа к сервису на стороне сервера, вы также можете отразить его (с помощью таких инструментов, как обратные прокси ) и включить туда все необходимые заголовки.
источник
Access-Control-Allow-Origin
в этом URL-адресе заголовки вообще не имеют значения - браузер откроет URL как обычно. Политика одинакового происхождения (и требование дляAccess-Control-Allow-Origin
заголовка) применяется только к вызовам Ajax.Есть своего рода хитрый способ сделать это, если на вашем сервере включен php. Измените эту строку:
url: 'http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml',
к этой строке:
url: '/path/to/phpscript.php',
а затем в php-скрипте (если у вас есть разрешение на использование функции file_get_contents ()):
<?php header('Content-type: application/xml'); echo file_get_contents("http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml"); ?>
Php, похоже, не возражает, если этот URL-адрес из другого происхождения. Как я уже сказал, это хакерский ответ, и я уверен, что с ним что-то не так, но он работает для меня.
Изменить: если вы хотите кэшировать результат в php, вот файл php, который вы должны использовать:
<?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; ?>
Кеширующий код берем отсюда .
источник
file_get_contents
вызов только в том случае, если самый последний XML-файл достаточно устарел. Также не забывайте заголовок Content-Type :-)