이 가이드를 사용하여 브라우저 콘솔 창에서 Access-Control-Allow-Origin
오류 메시지와 관련된 일반적인 문제를 해결하세요. 다음은 오류 메시지의 예입니다.
- 로드하지 못함 ... Access-Control-Allow-Origin' 헤더 없음
- 교차 출처 요청 차단됨: 동일 출처 정책으로 인해 원격 리소스 읽기가 허용되지 않습니다... 이유: CORS 헤더 'Access-Control-Allow-Origin' 누락
- 로드하지 못함 ... 실행 전 요청에 대한 응답이 액세스 제어 검사를 통과하지 못함 : 요청된 리소스에 'Access-Control-Allow-Origin' 헤더가 없습니다. 따라서 ...출처에 액세스할 수 없음
이 문서에서는 다음과 같은 주제를 다룹니다.
오류 원인
브라우저 기반 웹 애플리케이션 App Framework 앱에서 외부 웹 서비스로부터 공유 리소스를 받기 위해 교차 출처 호출을 시도하고 있습니다. 이를 CORS(Cross-Origin-Resource-Sharing) 요청이라고 합니다.
그러한 교차 출처 호출을 관리하는 브라우저 기반의 CORS 표준이 있습니다. 특정 조건이 충족되지 않으면 오류가 발생할 수 있습니다.
사용자의 웹 애플리케이션 및 원격 외부 서비스에서 의도적으로 허용하지 않는 사용 사례와 관련된 것일 수 있으므로 반드시 버그라고 할 수는 없습니다.
한 출처(www.origin1.com)가 다른 출처(www.origin2.com)를 호출할 때 이를 교차 출처 요청이라고 합니다. 이 요청이 작동하려면 특정 조건이 마련되어 있어야 합니다. 호출되는 외부 서비스(www.origin2.com)는 응답 시 HTTP 헤더 Access-Control-Allow-Origin
을 반환해야 합니다.
외부 서비스가 이 헤더를 반환하지 않으면 CORS 스펙에 대한 브라우저의 규정 준수가 요청을 중지하며 위의 오류 중 하나가 반환됩니다.
문제 해결하기 질문
- 호출의 시작점 URL(또는 출처)이란 무엇인가요?
때때로 이것은 오류 메시지 자체에 있습니다. - 외부 서비스의 URL은 무엇인가요?
이는 종종 콘솔 오류 메시지에 있습니다. - 무엇이 검색되고 있으며, 그 이유는 무엇인가요? PNG 파일인가요? 스크립트, CSS 또는 글꼴 파일인가요? 정확히 무엇이 검색되고 있으며 용도는 무엇인가요?
이를 통해 사용 사례와 이 원격 위치의 자산이 중요한 이유에 대한 통찰력을 얻을 수 있습니다. - 이 외부 리소스를 이용하려면 인증이 필요합니까?
리디렉션이 필요한 경우에는Access-Control-Allow-Origin
헤더가 반환되지 않을 수 있으며 호출이 실패합니다. 리소스의 URL을 새 시크릿 브라우저 탭으로 직접 복사합니다. 이는 일반적인 상황에서 액세스할 수 있는지 여부를 테스트하는 데 유용할 수 있지만 웹 앱의 코드에서 작동한다는 보장은 없습니다. - OPTIONS HTTP 메소드 호출이 브라우저의 네트워크 탭에 보이나요?
사용자 지정 요청 헤더, 인증 또는 기타 조건이 교차 출처 요청에 존재하면 브라우저가 추가 HTTP 호출을 합니다. 이를 실행 전 호출이라고도 합니다. 웹 앱의 코드에서 명시적으로 이를 만들지는 않고, 백그라운드의 브라우저가 만드는데 CORS 사양 표준의 일부입니다.
이 OPTIONS 호출을 하면 호출의 응답에 특정 값이 있어야 호출이 성공하고 리소스에 대한 실제 HTTP 호출이 발생합니다. OPTIONS 호출에 실패하면 리소스가 검색되지 않고 브라우저 콘솔에 CORS 오류가 표시됩니다. OPTIONS 호출이 보이면 적어두세요. 또한 OPTIONS 호출 전에 리디렉션(상태 302) 호출이 발생하는 경우에도 적어두세요. OPTIONS 호출에서 리디렉션이 발생하면 OPTIONS 호출이 실패할 가능성이 높습니다. 즉, 리소스를 받기 위한 호출도 실패하고 CORS 오류가 발생한다는 의미입니다. - 외부 리소스를 받기 위한 사용 사례란 무엇인가요?
이 외부 리소스를 먼저 검색하는 이유를 알아보세요. 이는 해결 방법이나 필요한 변경 사항을 마련할 때 중요할 수 있습니다. -
HAR 파일을 생성합니다.
실패한 호출의 스냅샷을 찍고 직전과 직후에 발생한 상황을 파악하면 문제를 디버그하는 데 도움이 되며 사용자가 이를 재현하지 않아도 됩니다. OPTIONS 호출과 리디렉션을 식별하는 동시에 요청과 응답의 헤더도 검사할 수 있습니다.
가능한 다음 단계
- 누가 외부 서버를 소유하나요? 아마도 서버는
Access-Control-Allow-Origin
헤더를 반환하여 CORS 사양 표준을 준수하도록 수정될 수 있습니다. 하지만 사내에서 제어하는 서버의 경우에도 이것이 반드시 필요한 것은 아닙니다. 특정 외부 서비스에서 리소스를 공유하고 싶지 않은 적절한 사유가 있을 수 있습니다. 외부 서버가 사내에서 제어되는 것이 아니라면 사용 사례가 유효한 것으로 가정하고 해당 공급업체와 협력하거나 다른 해결 방법을 생각해 낼 수 있습니다. - 앱이Zendesk App Framework를 사용하여 작성되었나요? 백엔드 프록시 서버는
client.request()
호출을 통해 이용할 수 있습니다. client.request의 설정에서cors:false
을 설정하여 이 프록시를 사용합니다. ‘거짓’은 설정의 기본값이기도 합니다. 프록시 서비스는 백엔드 서비스여서 브라우저 기반의 CORS 사양을 준수하지 않아도 되므로 프록시를 사용하여 교차 출처 호출에 성공할 수도 있습니다.
이 방법도 만병통치약은 아닙니다. 프록시 서비스는 외부 서비스에서 이진 파일 또는 이진 정보 검색을 지원하지 않습니다. 이것이 해결책이 아닌 다른 앱별 이유가 있을 수도 있습니다. - 리소스를 웹 앱에 바로 임베드할 수 있나요? 여러 출처에서 리소스를 얻으려고 하는 대신 웹 앱에 포함하는 것을 고려하세요. 이렇게 하면 교차 출처 호출을 완전히 피하고(이제는 로컬 리소스이기 때문) 모든 CORS 문제를 해결할 수 있습니다. 하지만 이것이 언제나 들어맞는 해결 방법은 아닙니다. 종종 외부 리소스 URL을 미리 알지 못하거나, 리소스가 너무 커서 로컬 리소스로 사용할 수 없거나, 리소스를 너무 자주 변경하여 로컬 고정 리소스로 다운로드할 수 없는 경우가 있습니다.
- 브라우저 버전이 무엇인가요? CORS 사양이 표준임에도 불구하고 브라우저에서 반환하는 오류 메시지는 다를 수 있습니다. Chrome은 Firefox와 다른 콘솔 메시지를 반환합니다.
- 종종 해결 방법이 없습니다. 종종 외부 서비스로부터의 리소스 요청은 브라우저 웹 앱의 맥락에서 공유되도록 의도하지 않는 경우가 있습니다. 리소스 소유자가 리소스를 공유할지 여부를 결정하며 이는 웹 앱에 달려 있지 않습니다. 디자인에 따라 설정될 수도 있습니다.
자세한 내용은 다음 리소스를 참조하세요.
- Wikipedia의 문서: 교차 출처 리소스 공유
- Web.Dev의 문서: 교차 출처 리소스 공유(CORS)
- Mozilla의 문서: 교차 출처 리소스 공유(CORS)
- Mozilla의 문서:
OPTIONS
- Fetch의 문서: 가져오기
- Fetch의 문서: CORS 프로토콜