[javascript] jQuery xml error ‘No’Access-Control-Allow-Origin ‘header is present on the request resource.’

http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml 에있는 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');
            }
         });
    }
);

나는 내 코드에서 잘못된 것이 보이지 않으므로 누군가가 내 코드에서 내가 뭘 잘못하고 있는지 그리고 어떻게 고칠 수 있는지 지적 할 수 있기를 바랍니다.



답변

동일 출처 정책 으로 인해 http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml배포 된 파일에서에 대한 ajax 호출을 수행 할 수 없습니다 .http://run.jsbin.com

제 (일명 소스로 원산지 ) 페이지와 대상 URL 서로 다른 도메인에있다 ( run.jsbin.comwww.ecb.europa.eu), 코드는 실제로 만들기 위해 시도하는 크로스 도메인 (CORS) 요청이 아닌 평범한 GET.

간단히 말해서, 동일 출처 정책에 따르면 브라우저는 HTML 페이지 의 동일한 도메인 에있는 서비스에 대한 ajax 호출 만 허용해야 합니다.

예:

의 페이지는 과 같은에있는 http://www.example.com/myPage.html서비스 만 직접 요청할 수 있습니다 . 서비스가 다른 도메인 (예 :)에서 호스팅되는 경우 브라우저는 예상대로 직접 호출하지 않습니다. 대신 CORS 요청을 시도합니다.http://www.example.comhttp://www.example.com/api/myServicehttp://www.ok.com/api/myService

간단히 말해서, 다른 도메인에서 (CORS) 요청 *을 수행하려면 브라우저에서 다음을 수행하십시오.

  • Origin원래 요청에 헤더를 포함하고 (페이지의 도메인을 값으로 사용) 평소와 같이 수행합니다. 그리고
  • 경우에만 서버 응답 이 요청이 포함 (적절한 헤더 Access-Control-Allow-Origin입니다 하나 그들 중 ) CORS 요청 수, 찾아보기는 전화 (거의 ** HTML 페이지가 같은 도메인에 있었던 경우는 것 정확히 방법)을 완료합니다.
    • 예상되는 헤더가 오지 않으면 브라우저는 단순히 포기합니다 (당신에게했던 것처럼).

* 위는 멋진 헤더가없는 일반 요청과 같은 간단한 요청 의 단계를 보여줍니다 GET. 요청이 단순하지 않은 경우 ( 콘텐츠 유형 으로 POSTwith와 application/json같이) 브라우저는 잠시 보류하고이를 이행하기 전에 먼저 OPTIONS대상 URL로 요청을 보냅니다 . 위와 마찬가지로이 OPTIONS요청에 대한 응답에 CORS 헤더가 포함 된 경우에만 계속됩니다 . 이 OPTIONS호출을 프리 플라이트 요청이라고합니다.

** 정규 통화와 CORS 통화간에 다른 차이점이 있기 때문에 거의 말하고 있습니다. 중요한 것은 일부 헤더가 응답에 있더라도 헤더에 포함되지 않은 경우 브라우저에서 선택되지 않는다는 것Access-Control-Expose-Headers 입니다.

그것을 고치는 방법?

오타 였나요? 때때로 JavaScript 코드는 대상 도메인에 오타 만 있습니다. 확인 했어? 페이지가 있으면 www.example.com정기적으로 www.example.com! 같은 api.example.com또는 심지어 example.com또는 브라우저에서 다른 도메인으로 www.example.com:8080간주 되는 다른 URL ! 예, 포트가 다르면 다른 도메인입니다!

헤더를 추가하십시오. CORS 를 활성화 하는 가장 간단한 방법 은 필요한 헤더 (as Access-Control-Allow-Origin)를 서버의 응답 에 추가하는 것 입니다. (각 서버 / 언어에는이를 수행하는 방법이 있습니다 . 여기에서 몇 가지 솔루션을 확인하십시오 .)

마지막 수단 : 서비스에 대한 서버 측 액세스 권한이없는 경우 서비스를 미러링하고 ( 역방향 프록시 와 같은 도구를 통해 ) 필요한 모든 헤더를 여기에 포함 할 수도 있습니다.


답변

서버에서 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");

?>

해당 URL이 다른 출처에서 온 경우 PHP는 신경 쓰지 않는 것 같습니다. 내가 말했듯이, 이것은 엉뚱한 대답이며, 문제가 있다고 확신하지만 저에게는 효과적입니다.

편집 : 결과를 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;

?>

캐싱 코드 가져 오기 여기 .


답변