jQuery xml error 'No'Access-Control-Allow-Origin 'header is present on the request resource.'


89

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');
            }
         });
    }
);

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



오류는 무엇이 잘못되었는지 정확히 알려줍니다. 귀하의 코드는 괜찮습니다. 문제는 귀하가 액세스하는 서버에 있습니다.
Kevin B

답변:


163

동일 출처 정책 으로 인해 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)를 서버의 응답 에 추가하는 것 입니다. (각 서버 / 언어에는이를 수행하는 방법이 있습니다 . 여기에서 몇 가지 솔루션을 확인하십시오 .)

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


2
감사합니다. 많은 정보입니다. 이제 진행에 필요한 조사를 수행 할 수 있습니다.
Bazinga777 2013

1
안녕하세요 acdcjunior, 액세스하려는 웹 서비스를 어떻게 미러링합니까?
Franva 2014

2
@Franva HTTP 서버 (예 : Tomcat, PHP가있는 Apache, ASP가있는 IIS)를 설정하고 모든 요청에 ​​대해 실제 서비스 (미러링중인 서비스)에 대한 소켓을 여는 페이지를 배치해야합니다. 실제 데이터를 요청한 다음 응답으로 제공합니다. 물론 코드 (Java, PHP, ASP 등)를 통해 수행합니다.
acdcjunior 2014

@acdcjunior 제 이해가 옳다면 저를 수정하십시오. 브라우저에 직접 URL을 입력하면 Access-Control-Allow-Origin 없이 자동으로 새 도메인 URL로 리디렉션됩니다 . 예를 들어 WIF를 사용하는 경우 사용자는 처음 로그인 할 때 타사 로그인 페이지로 리디렉션됩니다.
machinarium

@machinarium 당신이 의미하는 바를 이해했는지 잘 모르겠지만 대답하려고 노력할 것입니다 (잘못된 것이 있으면 알려주세요) : 브라우저의 주소 표시 줄에 URL을 입력하면 Access-Control-Allow-Origin해당 URL의 헤더는 전혀 중요하지 않습니다. 브라우저는 평소처럼 URL을 엽니 다. 동일 출처 정책 (및 Access-Control-Allow-Origin헤더에 대한 요구 사항 )은 Ajax 호출에만 적용됩니다.
acdcjunior 2014-07-17

29

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

?>

캐싱 코드 가져 오기 여기 .


3
더 나은 솔루션은 서버 측에서 XML 파일을 캐시 file_get_contents하고 가장 최근의 XML 파일이 충분히 날짜가있는 경우 에만 호출을 수행하는 것 입니다. 또한, 콘텐츠-Type 헤더를 :-) 잊지 마세요
sffc

이 대답을 우연히 발견했습니다. 질문 : PHP 파일은 GET 데이터를 가져 와서 해당 URL에 제출하는 것을 어떻게 알 수 있습니까? POST 된 데이터에서도 작동합니까?
mpdc 2014-10-29

제출하지 않습니다. 파일을 가져 와서 로컬에 저장 한 다음 해당 파일이 로컬에서 요청한 php 파일 인 것처럼 뿜어냅니다. 로컬에서 캐시 된 파일이 주어진 최대 수명보다 오래된 경우 다른 복사본을 검색하고 저장합니다.
생각
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.