XMLHttpRequest가 XXX No 'Access-Control-Allow-Origin'헤더를로드 할 수 없습니다.


111

tl; dr; 동일 원산지 정책 정보

express.js 서버의 인스턴스를 시작하는 Grunt 프로세스가 있습니다. 이것은 Chrome (최신 버전)의 개발자 콘솔에있는 오류 로그에 다음과 같은 내용이 표시되는 빈 페이지를 제공하기 시작했을 때까지 완벽하게 작동했습니다.

XMLHttpRequest가 https://www.example.com/을 로드 할 수 없습니다 . 요청 된 리소스에 'Access-Control-Allow-Origin'헤더가 없습니다. 따라서 원본 ' http : // localhost : 4300 '은 액세스가 허용되지 않습니다.

페이지에 액세스하지 못하게하는 이유는 무엇입니까?


저는 웹 사이트에서 일하고 있는데 5 분 전에는 괜찮 았습니다.
Peter David Carter

1
CORS 헤더를 발행합니까? 아마도 코드를 공유했다면 더 쉽게 볼 수있을 것입니다
Jaromanda X

그럴듯 해. 어느 부서에 문의해야합니까? 난 그냥 ... 대부분 backbone.marionette 물건을
피터 데이비드 카터

네. 어차피 부서의 조직이 항상 균일하지는 않다고 생각하므로 모호한 질문 일 수 있지만 제 회사의 백엔드 / 라우팅 / 시스템 관리자 관련 사항을 조금 알고 싶습니다. 미래에 문제가 생기면 도와 드릴 수 있습니다.
Peter David Carter

나는 당신의 작업 내 서버 측의 누군가에게 물어볼 것입니다. 이전에 액세스 할 수 있었다면 변경했을 것입니다.
Larry Lane

답변:


205

tl; dr — 관련 부분을 더 쉽게 찾을 수 있도록 끝에 요약과 답변의 제목이 있습니다. 모든 것을 읽는 것이 다른 상황에서 어떻게 적용 되는지 더 쉽게 볼 수있는 이유 를 이해하는 데 유용한 배경을 제공하기 때문에 권장 됩니다.

동일 원산지 정책 정보

이것은 동일 출처 정책 입니다. 브라우저에 의해 구현 된 보안 기능입니다.

당신의 특별한 경우는이 XMLHttpRequest를 구현하는 방법을 보여주고있다 (그리고 당신이 패치를 사용한다면 당신은 동일한 결과를 얻을 수 있습니다)뿐만 아니라 (예에로드 된 이미지와 같은 다른 것들에 적용 <canvas>에로드 또는 문서 <iframe>단지와 함께) 약간 다른 구현.

(이상하게도 CSS 글꼴에도 적용되지만 발견 된 파운드리가 동일 출처 정책에서 일반적으로 다루는 보안 문제가 아니라 DRM을 주장했기 때문입니다.)

SOP의 필요성을 보여주는 표준 시나리오는 다음 세 문자 로 설명 할 수 있습니다 .

  • Alice는 웹 브라우저를 가진 사람입니다.
  • Bob은 웹 사이트를 운영합니다 ( https://www.[website].com/예 :
  • Mallory는 웹 사이트를 실행합니다 ( http://localhost:4300귀하의 예에서)

Alice는 Bob의 사이트에 로그인하고 일부 기밀 데이터를 가지고 있습니다. 아마도 회사 인트라넷 (LAN의 브라우저에서만 액세스 가능) 또는 온라인 뱅킹 (사용자 이름과 비밀번호를 입력 한 후 얻은 쿠키로만 액세스 가능) 일 수 있습니다.

Alice는 Alice의 브라우저가 Bob의 웹 사이트 (쿠키가있는 IP 주소 등)에 HTTP 요청을하도록하는 JavaScript가있는 Mallory의 웹 사이트를 방문합니다. 이것은 사용하는 등 간단하게 할 수 XMLHttpRequest와 읽기 responseText.

브라우저의 동일 출처 정책은 JavaScript가 Bob의 웹 사이트 (Bob과 Alice가 Mallory가 액세스하는 것을 원하지 않음)에서 반환 한 데이터를 읽지 못하도록합니다. 당신은, 예를 들어, 사용하여 이미지를 표시 할 수있는 (주 <img>이미지의 내용이) 자바 스크립트 (또는 말로리에 노출되지 않기 때문에 당신이이 경우에 믹스로 캔버스 던져하지 않는 한 ... 기원에 걸쳐 요소를 합니다 동일 기원을 생성을 위반 오류).


같은 원산지 정책이 필요하지 않다고 생각할 때 적용되는 이유

주어진 URL에 대해 SOP가 필요하지 않을 수 있습니다. 이러한 경우 몇 가지 일반적인 시나리오는 다음과 같습니다.

  • Alice, Bob, Mallory는 같은 사람입니다.
  • Bob은 전적으로 공개 정보를 제공하고 있습니다.

… 그러나 브라우저는 위 중 하나가 사실인지 알 수있는 방법이 없으므로 신뢰는 자동이 아니며 SOP가 적용됩니다. 브라우저가 다른 웹 사이트에 제공된 데이터를 제공하기 전에 명시 적으로 권한을 부여해야합니다.


동일한 출처 정책이 웹 페이지의 JavaScript에만 적용되는 이유

브라우저 확장 *, 브라우저 개발자 도구의 네트워크 탭 및 Postman과 같은 응용 프로그램이 설치된 소프트웨어입니다. 다른 웹 사이트 를 방문했기 때문에 한 웹 사이트에서 다른 웹 사이트에 속한 JavaScript로 데이터를 전달하지 않습니다 . 소프트웨어를 설치하려면 일반적으로보다 의식적인 선택이 필요합니다.

위험으로 간주되는 제 3 자 (몰 로리)가 없습니다.

*출처 간 문제를 방지하려면 브라우저 확장을 신중하게 작성해야합니다. 예를 들어 Chrome 문서를 참조하십시오 .


JS로 읽지 않고 페이지에 데이터를 표시 할 수있는 이유

Mallory의 사이트로 인해 브라우저가 제 3 자로부터 데이터를 가져 와서 표시 할 수있는 여러 상황이 있습니다 (예 : <img>이미지를 표시하는 요소 추가 ). 그러나 Mallory의 JavaScript가 해당 리소스의 데이터를 읽을 수는 없지만 Alice의 브라우저와 Bob의 서버 만 그렇게 할 수 있으므로 여전히 안전합니다.


CORS

오류 메시지에 언급 된 Access-Control-Allow-OriginHTTP 응답 헤더는 CORS 표준의 일부로 Bob이 Mallory의 사이트에 Alice의 브라우저를 통해 데이터에 액세스 할 수있는 권한을 명시 적으로 부여 할 수 있습니다.

기본 구현에는 다음이 포함됩니다.

Access-Control-Allow-Origin: *

… 모든 웹 사이트에서 데이터를 읽을 수 있도록 응답 헤더에.

Access-Control-Allow-Origin: http://example.com/

… 특정 사이트 만 액세스하도록 허용하고 Bob은 Origin 요청 헤더를 기반으로 동적으로 생성하여 모든 사이트가 아닌 여러 사이트에서 액세스 할 수 있도록 허용합니다.

Bob이 해당 응답 헤더를 설정하는 방법에 대한 세부 사항은 Bob의 HTTP 서버 및 / 또는 서버 측 프로그래밍 언어에 따라 다릅니다. 이 다양한 일반적인 구성을위한 가이드의 모음 그 힘의 도움.

CORS 규칙이 적용되는 모델

NB : 일부 요청은 복잡하며 브라우저가 JS가 원하는 GET / POST / PUT / Whatever 요청을 보내기 전에 서버가 응답해야하는 프리 플라이트 OPTIONS 요청을 보냅니다. Access-Control-Allow-Origin특정 URL 에만 추가 되는 CORS 구현은 종종 이로 인해 실패합니다.


분명히 CORS를 통해 권한을 부여하는 것은 Bob이 다음과 같은 경우에만 수행 할 수있는 작업입니다.

  • 데이터가 비공개가 아니 거나
  • 말로리는 신뢰 받았다

하지만 저는 밥이 아닙니다!

Mallory 가 제어하지 않는 Bob의 웹 사이트에서 가져와야 하기 때문에이 헤더를 추가하는 표준 메커니즘 이 없습니다.

Bob이 공용 API를 실행중인 경우 CORS를 켜는 메커니즘이있을 수 있습니다 (예 : 특정 방식으로 요청을 형식화하거나 Bob의 사이트에 대한 개발자 포털 사이트에 로그인 한 후 구성 옵션). 이것은 Bob이 구현 한 메커니즘이어야합니다. Mallory는 Bob의 사이트에있는 문서를 읽고 사용할 수 있는지 확인하거나 Bob과 대화하여 CORS를 구현하도록 요청할 수 있습니다.


"프리 플라이트에 대한 응답"을 언급하는 오류 메시지

일부 교차 오리진 요청은 프리 플라이트 됩니다.

이것은 (대략적으로 말하면) 다음과 같은 교차 출처 요청을 시도 할 때 발생합니다.

  • 쿠키와 같은 자격 증명 포함
  • 일반 HTML 양식으로 생성 할 수 없습니다 (예 : 양식의에서 사용할 수없는 사용자 정의 헤더 또는 Content-Type 포함 enctype).

프리 플라이트가 필요한 작업을 올바르게 수행중인 경우

이러한 경우에 다음 이 답변의 나머지 부분은 계속 적용 하지만 당신은 또한 서버가 될 것이다 (프리 플라이트 요청을 수신 할 수 있는지 확인해야합니다 OPTIONS(그리고 GET, POST또는 오른쪽으로에 보내려고) 및 응답했다 어떤 Access-Control-Allow-Origin헤더뿐만 아니라 Access-Control-Allow-MethodsAccess-Control-Allow-Headers특정의 HTTP 메소드 또는 헤더를 허용합니다.

실수로 프리 플라이트를 트리거하는 경우

때때로 사람들은 Ajax 요청을 구성하려고 할 때 실수를하고, 때때로 이러한 실수로 인해 프리 플라이트가 필요합니다. API가 원본 간 요청을 허용하도록 설계되었지만 프리 플라이트가 필요한 항목이 필요하지 않은 경우 액세스가 중단 될 수 있습니다.

이를 유발하는 일반적인 실수는 다음과 같습니다.

  • Access-Control-Allow-Origin요청에 다른 CORS 응답 헤더 를 넣으려고합니다 . 이는 요청에 속하지 않으며 도움이되는 작업을 수행하지 않으며 (자신에게 권한을 부여 할 수있는 권한 시스템의 요점은 무엇입니까?) 응답에만 나타나야합니다.
  • 풋 시도 Content-Type: application/json(일반적으로 때 저자 혼란의 내용을 설명 할 요청 본문이없는 GET 요청에 헤더 Content-TypeAccept).

두 경우 모두 추가 요청 헤더를 제거하면 프리 플라이트 (단순 요청을 지원하지만 프리 플라이트 요청이 아닌 API와 통신 할 때 문제가 해결됨)가 필요하지 않을 수 있습니다.


불투명 한 응답

때로는 HTTP 요청을해야하지만 응답을 읽을 필요가 없습니다. 예를 들어 기록을 위해 서버에 로그 메시지를 게시하는 경우.

당신이 사용하는 경우 API (아닌를 ), 당신은 그것을 사용 CORS 시도하지 구성 할 수 있습니다.fetchXMLHttpRequest

이것은 CORS에 필요한 작업을 수행하도록 허용하지 않습니다. 응답을 읽을 수 없습니다. 프리 플라이트가 필요한 요청을 할 수 없습니다.

간단한 요청을하고 응답을 보지 않고 개발자 콘솔에 오류 메시지를 채우지 않도록합니다.

이를 수행하는 방법은 fetchCORS를 사용하여 응답을 볼 수있는 권한이없는 요청을 할 때 제공되는 Chrome 오류 메시지에 설명되어 있습니다 .

CORS 정책에 의해 https://example.com/' https://example.net' 출처 ' '에서 가져 오기에 대한 액세스 가 차단되었습니다 Access-Control-Allow-Origin. 요청 된 리소스에 ' '헤더가 없습니다 . 불투명 한 응답이 요구 사항을 충족하는 경우 요청 모드를 'no-cors'로 설정하여 CORS가 비활성화 된 리소스를 가져옵니다.

그러므로:

fetch("http://example.com", { mode: "no-cors" });

CORS의 대안

JSONP

Bob은 또한 CORS가 나오기 전에 사람들이 교차 출처 Ajax를 수행 한 방법 인 JSONP 와 같은 해킹을 사용하여 데이터를 제공 할 수 있습니다 .

그것은 Mallory의 페이지에 데이터를 주입하는 JavaScript 프로그램의 형태로 데이터를 제시함으로써 작동합니다.

Mallory는 Bob이 악성 코드를 제공하지 않도록 신뢰해야합니다.

공통 주제에 유의하십시오. 데이터를 제공하는 사이트는 제 3 자 사이트가 브라우저로 전송하는 데이터에 액세스해도 괜찮다는 것을 브라우저에 알려야합니다.

JSONP는 <script>페이지에 이미있는 함수를 호출하는 JavaScript 프로그램의 형태로 데이터를로드 하는 요소를 추가하는 방식으로 작동하므로 JSON을 반환하는 URL에서 JSONP 기술을 사용하려고하면 실패 (일반적으로 CORB 오류)가 발생합니다. JavaScript가 아닙니다.

두 리소스를 단일 Origin으로 이동

JS가 실행되는 HTML 문서와 요청되는 URL이 동일한 출처 (동일한 체계, 호스트 이름 및 포트 공유)에있는 경우 동일한 출처 정책이 기본적으로 권한을 부여합니다. CORS는 필요하지 않습니다.

프록시

말로리 서버 측 코드를 사용하여 데이터를 가져올 수 있습니다 (그런 다음 평소와 같이 HTTP를 통해 서버에서 Alice의 브라우저로 전달할 수 있음).

다음 중 하나입니다.

  • CORS 헤더 추가
  • 응답을 JSONP로 변환
  • HTML 문서와 동일한 출처에 존재

해당 서버 측 코드는 CORS Anywhere와 같은 제 3 자에 의해 작성 및 호스팅 될 수 있습니다. 이것의 프라이버시 의미에 유의하십시오. 타사는 서버에서 누가 무엇을 프록시하는지 모니터링 할 수 있습니다.

Bob은이를 위해 어떤 권한도 부여 할 필요가 없습니다.

Mallory와 Bob 사이에 있기 때문에 여기에는 보안 관련이 없습니다. Bob이 Mallory가 Alice라고 생각하고 Alice와 Bob간에 기밀로 유지되어야하는 데이터를 Mallory에 제공 할 방법이 없습니다.

따라서 Mallory는이 기술을 사용하여 공용 데이터 를 읽을 수만 있습니다 .

그러나 다른 사람의 웹 사이트에서 콘텐츠를 가져 와서 직접 표시하는 것은 저작권 위반이며 법적 조치를 취할 수 있습니다.

웹 앱 이외의 내용 작성

"동일한 출처 정책이 웹 페이지의 JavaScript에만 적용되는 이유"섹션에서 언급했듯이 웹 페이지에 JavaScript를 작성하지 않으면 SOP를 피할 수 있습니다.

그렇다고 JavaScript와 HTML을 계속 사용할 수 없다는 의미는 아니지만 Node-WebKit 또는 PhoneGap과 같은 다른 메커니즘을 사용하여 배포 할 수 있습니다.

브라우저 확장

브라우저 확장은 동일한 원본 정책이 적용되기 전에 응답에 CORS 헤더를 삽입 할 수 있습니다.

이는 개발에 유용 할 수 있지만 프로덕션 사이트에는 실용적이지 않습니다 (사이트의 모든 사용자에게 브라우저의 보안 기능을 비활성화하는 브라우저 확장 프로그램을 설치하도록 요청하는 것은 불합리합니다).

또한 간단한 요청으로 만 작동하는 경향이 있습니다 (프리 플라이트 OPTIONS 요청을 처리 할 때 실패 함).

로컬 개발 서버 가 있는 적절한 개발 환경을 갖는 것이 일반적으로 더 나은 접근 방식입니다.


기타 보안 위험

SOP / CORS는 독립적으로 처리해야하는 XSS , CSRF 또는 SQL 주입 공격을 완화하지 않습니다 .


요약

  • 당신이 할 수있는 일은 없다 당신의 사람에게 CORS 액세스를 가능하게 할 것이다 클라이언트 측 코드를 다른 사람의 서버.
  • 서버를 제어하는 ​​경우 요청이 작성됩니다. CORS 권한을 추가하십시오.
  • 제어하는 사람과 친한 경우 : CORS 권한을 추가하도록 요청하십시오.
  • 공공 서비스 인 경우 :
    • API 문서를 읽고 클라이언트 측 JavaScript로 액세스하는 방법에 대해 설명합니다.
      • 특정 URL을 사용하라고 말할 수 있습니다.
      • JSONP를 지원할 수 있습니다.
      • 클라이언트 측 코드에서 교차 출처 액세스를 전혀 지원하지 않을 수 있습니다 (특히 각 요청에서 개인화 된 API 키를 전달해야하는 경우 보안 근거에 대한 의도적 인 결정일 수 있음).
    • 필요하지 않은 프리 플라이트 요청을 트리거하지 않았는지 확인하십시오. API는 단순 요청에 대한 권한을 부여 할 수 있지만 프리 플라이트 된 요청에는 부여하지 않을 수 있습니다.
  • 위의 어느 것도 적용되지 않는 경우 : 브라우저가 대신 서버와 통신하도록 한 다음 서버가 다른 서버에서 데이터를 가져와 전달하도록합니다. (사용할 수있는 공개적으로 액세스 가능한 리소스에 CORS 헤더를 첨부하는 타사 호스팅 서비스도 있습니다.)

로컬 LAN 웹 서버를 실행하고 IP / URL에서 ajax로드를 시도하면 작동합니까? 나는 아직 그것을 시도하지 않았습니다. 내 웹 서버가 JSON 데이터를 returing로 MCU 것
piekarz Ciasto

@Ciastopiekarz — 일반적인 동일한 출처 / 다른 출처 규칙이 적용됩니다. 일반 네트워크 라우팅 규칙이 적용됩니다.
Quentin

25
가장 완벽한 내가 읽은 적이했습니다 대답 대신 고르에 대한 단지 링크 ..
pungggi

@Quentin-와우! +1! 앨리스는 CORS 확장자를 사용하는 경우 제가 이해하는거야 것은 그래서, 서버는 그녀의 HTTP 호출이 있다고 생각 하지 자바 스크립트에서하지만 정상적인 같은 기원 요구와 같은 브라우저 확장 및 취급 그것에서?
snippetkid

@snippetkid — 아니요. 일반적인 경우 서버는 항상 응답으로 CORS 헤더를 보내고 요청이 어디에서 왔는지 신경 쓰지 않습니다. 응답의 CORS 헤더를 기반으로 JS에 대한 데이터에 대한 액세스를 허용하거나 거부하는 것은 브라우저의 책임입니다. (프리 플라이트 요청에 관해서는 서버에서 / little / 더 복잡 해짐)
Quentin

3

대상 서버는 원본 간 요청을 허용해야합니다. Express를 통해 허용하려면 http 옵션 요청을 처리하기 만하면됩니다.

app.options('/url...', function(req, res, next){
   res.header('Access-Control-Allow-Origin', "*");
   res.header('Access-Control-Allow-Methods', 'POST');
   res.header("Access-Control-Allow-Headers", "accept, content-type");
   res.header("Access-Control-Max-Age", "1728000");
   return res.sendStatus(200);
});

3

이것은 수락 된 답변에 언급되어 있지 않습니다.

  • 이 정확한 질문에는 해당되지 않지만 해당 문제를 검색하는 다른 사용자에게 도움이 될 수 있습니다.
  • 이것은 경우에 따라 CORS 오류를 방지하기 위해 클라이언트 코드에서 수행 할 수있는 작업입니다 .

단순 요청 을 사용할 수 있습니다 .
'단순 요청'을 수행하려면 요청이 여러 조건을 충족해야합니다. 예를 들어 POST, GETHEAD메서드 만 허용하고 특정 헤더 만 허용합니다 ( 여기에서 모든 조건을 찾을 수 있음 ).

클라이언트 코드가하는 경우 명시 적 설정은 헤더의 영향을받지 않습니다 (예 : "승인")가 요청에 수정 값을 수있는 몇 가지 클라이언트가 어떤 "표준이 아닌"값으로 이용 약관을 읽고 동의에 서버를 일으키는 원인이 자동으로 이러한 헤더를 설정하는 것을 발생 Simple Request-CORS 오류를 제공합니다.


2

이것은 CORS 오류로 인해 발생합니다. CORS는 Cross Origin Resource Sharing의 약자입니다. 간단히 말해서이 오류는 다른 도메인에서 도메인 / 리소스에 액세스하려고 할 때 발생합니다.

여기에 대해 자세히 알아보기 : jquery의 CORS 오류

이 문제를 해결하려면 다른 도메인에 대한 액세스 권한이있는 경우 서버에서 Access-Control-Allow-Origin을 허용해야합니다. 이것은 헤더에 추가 할 수 있습니다. 모든 요청 / 도메인 또는 특정 도메인에 대해이를 활성화 할 수 있습니다.

CORS (Cross-Origin Resource Sharing) 요청 후 작업을 가져 오는 방법

이 링크는 도움이 될 수 있습니다.


0

이 CORS 문제는 (다른 원인에 대해) 더 자세히 설명되지 않았습니다.

현재 다른 이유로이 문제가 발생합니다. 내 프런트 엔드는 'Access-Control-Allow-Origin'헤더 오류도 반환합니다.

이 헤더가 제대로 반영되지 않았기 때문에 잘못된 URL을 가리켰다는 것뿐입니다. localhost (프런트 엔드)-> 보안되지 않은 http (https로 가정)에 대한 호출, 프런트 엔드의 API 엔드 포인트가 올바른 프로토콜을 가리키는 지 확인하십시오.


0

Chrome 콘솔에서 동일한 오류가 발생했습니다.

내 문제는 http://대신을 사용하여 사이트로 이동하려고했습니다 https://. 따라서 수정할 것이 없었으며 .NET을 사용하여 동일한 사이트로 이동해야했습니다 https.


-1

헤더를 추가하여 "Get"요청을 "Options"요청으로 변환합니다. 그래서 Cors 정책 문제가 발생합니다. 서버에 "옵션"요청을 구현해야합니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.