프리 플라이트 요청에 대한 응답이 액세스 제어 확인을 통과하지 못함


457

Amazon Web Services에서 REST API를 호출하기 위해 ngResource를 사용 하여이 오류가 발생합니다.

XMLHttpRequest가 http://server.apiurl.com:8000/s/login?login=facebook을 로드 할 수 없습니다 . 프리 플라이트 요청에 대한 응답이 액세스 제어 확인을 통과하지 못함 : 요청 된 리소스에 'Access-Control-Allow-Origin'헤더가 없습니다. 따라서 원본 ' http : // localhost '는 액세스가 허용되지 않습니다. 405 오류

서비스:

socialMarkt.factory('loginService', ['$resource', function($resource){    
    var apiAddress = "http://server.apiurl.com:8000/s/login/";
    return $resource(apiAddress, { login:"facebook", access_token: "@access_token" ,facebook_id: "@facebook_id" }, {
                getUser: {method:'POST'}
            });
}]);

제어 장치:

[...]
loginService.getUser(JSON.stringify(fbObj)),
                function(data){
                    console.log(data);
                },
                function(result) {
                    console.error('Error', result.status);
                }
[...]

Chrome을 사용하고 있는데이 문제를 해결하기 위해 무엇을해야할지 모르겠습니다. 서버에서 origin의 헤더를 허용하도록 구성했습니다 localhost.


혼란스러운 : "서버를 구성 했습니까?"또는 "아마존 웹 서비스의 나머지 API"입니까?
dandavis

3
서버 측에서 CORS를 활성화하기에 충분하지 않습니다. 응답 헤더 샘플 게시
charlietfl

4
어느 쪽이든 당신의 다운 투표가 잘못되었습니다. 그는 자신의 파일을 로컬 컴퓨터에서 호스팅하고 있습니다. 그가 백엔드에서 어떤 종류의 conf를하든 상관 없습니다. Angular는이 사전 비행을 허용하지 않습니다.
E. Maggini

3
댓글에 대한 Thx, 그것은 브라우저를 보안 설정으로 설정했을 때 작동했습니다
Andre Mendes

1
@Andre 그러나 보안을 끄는 것은 보안에 타협하고, 문제를 해결하지
못한

답변:


240

CORS 문제가 발생했습니다.

이 문제를 해결 / 해결하는 방법에는 여러 가지가 있습니다.

  1. CORS를 끕니다. 예를 들어 크롬에서 cors를 끄는 방법
  2. 브라우저 용 플러그인 사용
  3. nginx와 같은 프록시를 사용하십시오. 설정 방법의 예
  4. 서버에 필요한 설정을 수행하십시오. 이는 EC2 인스턴스에로드 한 웹 서버의 요소입니다 ( "Amazon 웹 서비스"의 의미라고 가정). 특정 서버의 경우 enable CORS 웹 사이트를 참조 할 수 있습니다 .

더 자세하게는 localhost에서 api.serverurl.com에 액세스하려고합니다. 이것은 도메인 간 요청의 정확한 정의입니다.

작업을 완료하기 위해 전원을 끄면 (확인, 다른 사이트를 방문하고 길을 따라 갈 수있는 경우 보안을 약화 시키십시오) 프록시를 사용하면 브라우저가 모든 요청이 로컬 호스트에서 온 것으로 생각하게됩니다 실제로 원격 서버를 호출하는 로컬 서버가 있습니다.

따라서 api.serverurl.com은 localhost : 8000 / api가되고 로컬 nginx 또는 다른 프록시가 올바른 대상으로 전송합니다.


대중적인 수요에 의해, 100 % 더 많은 CORS 정보 .... 동일한 맛!


그리고 downvoters를 위해 .... CORS를 우회하는 것은 단순히 프론트 엔드를 배우는 사람들에게 보여지는 것입니다. https://codecraft.tv/courses/angular/http/http-with-promises/


774
제대로 구현 CORS의 명백한 탈락
charlietfl

40
투표하기 쉽습니다. 내 친구 자신을 위험을 감수하기가 쉽지 않습니다. 그리고이 모든 것이 개발 환경에서 정확하게 작동합니다.
E. Maggini

3
실제로 효과가있었습니다. 웹 보안을 사용하지 않도록 플래그를 추가했습니다. 개발은 괜찮습니다.
Andre Mendes

15
@charlietfl 어떻게?
GreenAsJade

3
당신은 내 하루를 저장 감사합니다. 첫 번째 옵션 만 사용 : C : \ Program Files (x86) \ Google \ Chrome \ Application> chrome.exe --user-data-dir = "C : \ Chrome dev session"--disable-web-security. From : stackoverflow.com/questions/3102819/…
Harsimer

169

내 "API 서버"는 PHP 응용 프로그램이므로이 문제를 해결하려면 아래 해결책이 있습니다.

index.php에 줄을 넣으십시오

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');

3
이 행을 복사 할 때주의해야하지만 메소드와 원점을 수정해야하지만 허용 된 답변보다 낫습니다.
Amir Savand

11
Angular 6 프로젝트에서 어디에 두어야합니까?
whatthefish

@CodyBugstein과 whatthefish는 출력 전에 넣어
Garet Claborn

일부 서버에만 필요한 헤더를 추가하면 클라이언트 앱이 작동을 멈췄습니다. 요청에 맞춤 헤더가 포함되어 있으면에 헤더가 표시되어야 Access-Control-Allow-Headers합니다.
z0r

47

AspNetCore 웹 API에서이 문제는 "Microsoft.AspNetCore.Cors"(1.1.1 버전)를 추가하고 Startup.cs에 아래 변경 사항을 추가하여 해결되었습니다.

public void ConfigureServices(IServiceCollection services)
{ 
    services.AddCors(options =>
    {
          options.AddPolicy("AllowAllHeaders",
                builder =>
            {
                    builder.AllowAnyOrigin()
                           .AllowAnyHeader()
                           .AllowAnyMethod();
                });
    });
    .
    .
    .
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{


    // Shows UseCors with named policy.
    app.UseCors("AllowAllHeaders");
    .
    .
    .
}

[EnableCors("AllowAllHeaders")]컨트롤러를 착용 하고


18
크로스 사이트 스크립팅 취약점으로 구축하려는 경우에 좋은 답변입니다! 절대로 이러지 마십시오! 보안 문제를 피하기 위해 액세스 할 수있는 도메인을 지정하십시오. CORS는 이유가 있습니다.
paqogomez 2016 년

2
ConfigureServices 메소드에서 @paqogomez를 더 명확하게하기 위해 services.AddCors (options => {options.AddPolicy ( "AllowSpecificOrigin", builder => {builder.WithOrigins ( " localhost" ) .AllowAnyOrigin () .AllowAnyHeader ()). AllowAnyMethod ();});}); 그리고 Configure 메소드에서 : app.UseCors ( "AllowSpecificOrigin");
Francisco Tena

28

CORS에 관해서는 몇 가지주의 사항이 있습니다. 첫째, 와일드 카드를 허용 *하지 않지만이 곳을 잡지 마십시오. 어딘가에서 읽었으며 지금 기사를 찾을 수 없습니다.

다른 도메인에서 요청하는 경우 허용 오리진 헤더를 추가해야합니다.

 Access-Control-Allow-Origin: www.other.com 

당신은 POST / PUT / PATCH 같은 서버 자원에 영향을, 그리고 마임 유형은 다음과 다른 경우 요청하게되는 경우 application/x-www-form-urlencoded, multipart/form-data또는 text/plain브라우저가 자동으로이를 허용 할 경우 비행 전 옵션은 서버에 확인을 요청하게됩니다 .

따라서 API / 서버는 이러한 OPTIONS 요청을 적절하게 처리해야하며, 적절하게 응답해야 access control headers하며 http 응답 상태 코드는이어야 200합니다.

헤더는 다음과 같아야합니다. 필요에 맞게 조정하십시오.

   Access-Control-Allow-Methods: GET, POST, PUT, PATCH, POST, DELETE, OPTIONS
   Access-Control-Allow-Headers: Content-Type
   Access-Control-Max-Age: 86400

max-age 헤더는 중요합니다. 제 경우에는 그것 없이는 작동하지 않을 것입니다. 브라우저에 "액세스 권한"의 유효 기간에 대한 정보가 필요하다고 생각합니다.

또한 다른 도메인에서 mime 으로 POST요청하는 application/json경우 이전에 언급 한 allow origin 헤더를 추가해야하므로 다음과 같습니다.

   Access-Control-Allow-Origin: www.other.com 
   Access-Control-Allow-Methods: GET, POST, PUT, PATCH, POST, DELETE, OPTIONS
   Access-Control-Allow-Headers: Content-Type
   Access-Control-Max-Age: 86400

사전 비행이 성공하고 필요한 정보를 모두 얻으면 실제 요청이 이루어집니다.

일반적으로 Access-Control초기 또는 비행 전 요청에서 요청한 모든 헤더가 작동하려면 응답에 제공되어야합니다.

이 링크 의 MDN 문서에 좋은 예가 있으며이 SO 게시물 도 확인해야합니다.


1
다음은 고르 기원에 대한 와일드 카드 사용할 수있는 방법에 대해 이야기 모질라 기사는 다음 링크 (내가 제대로 이해 해요 경우) 자격 증명을 사용 그래서 분명히 이것은 단지 적용
Helzgate

와일드 카드를 사용하고 요청을 승인하기 위해 베어러 토큰을 제출하고 있으며 제대로 작동하므로 위에 제공된 링크가 자격 증명과 관련하여 어떤 내용을 참조하는지 잘 모르겠습니다. 내 문제는 .Net Core에서 CORS 정책을 만들 때 추가하지 않았다는 것 .AllowCredentials()입니다. .AllowCredentials()모든 것을 추가 한 후 작동했습니다.
Helzgate 2016 년

15

JavaScript XMLHttpRequestFetch 는 동일한 출처 정책을 따릅니다. 따라서 XMLHttpRequest 또는 Fetch를 사용하는 웹 응용 프로그램은 자체 도메인에 HTTP 요청 만 할 수 있습니다.

출처 : https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

서버 측에서 Access-Control-Allow-Origin : * HTTP 헤더 를 보내야합니다 .

Apache를 HTTP 서버로 사용하는 경우 다음과 같이 Apache 구성 파일에 추가 할 수 있습니다.

<IfModule mod_headers.c>
    Header set Access-Control-Allow-Origin "*"
</IfModule>

Apache에서는 Mod_headers가 기본적으로 활성화되어 있지만 다음을 실행하여 활성화 할 수 있습니다.

 a2enmod headers

Apache 구성 파일은 어디에서 찾을 수 있습니까?
Shubham Arya

리눅스 데비안의 @ShubhamArya 기본 위치는 다음과 같습니다./etc/apache2/apache2.conf
Tadej

창문에서 어디서 찾을 수 있습니까?
Shubham Arya

10

크롬 확장 프로그램을 작성하는 경우

manifest.json도메인에 대한 권한 을 추가 해야합니다.

"permissions": [
   "http://example.com/*",
   "https://example.com/*"
]

1
또한 www 접두사가 있는지 확인하십시오
Vlas Bashynskyi

8

우연히 IIS 서버를 사용하는 경우 HTTP 요청 헤더 옵션에서 아래 헤더를 설정할 수 있습니다.

Access-Control-Allow-Origin:*
Access-Control-Allow-Methods: 'HEAD, GET, POST, PUT, PATCH, DELETE'
Access-Control-Allow-Headers: 'Origin, Content-Type, X-Auth-Token';

이 모든 게시물, 가져 오기 등이 제대로 작동합니다.



5

PHP에서는 헤더를 추가 할 수 있습니다 :

<?php
header ("Access-Control-Allow-Origin: *");
header ("Access-Control-Expose-Headers: Content-Length, X-JSON");
header ("Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS");
header ("Access-Control-Allow-Headers: *");
...

고마워, 그것은 나를 위해 일했다! 테스트 및 프로덕션 환경에서. https : //를 사용하여도
Jose Seie

1
@atiruz 솔루션 주셔서 감사합니다. 이것은 내가 라인을 추가했을 때 작동합니다header ("Access-Control-Expose-Headers: Content-Length, X-JSON");
Silambarasan RD

5

Node JS 애플리케이션에서 출처 간 요청 문제를 해결하려면 다음을 수행하십시오.

npm i cors

그리고 단순히 아래 줄을 app.js

let cors = require('cors')
app.use(cors())

3
이것은 단지, 표현의 js 응용 프로그램에서 모든 노드 응용 프로그램을 작동
DrCord

3

내 Apache VirtualHost 구성 파일에서 다음 줄을 추가했습니다.

Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header always set Access-Control-Max-Age "1000"
Header always set Access-Control-Allow-Headers "x-requested-with, Content-Type, origin, authorization, accept, client-security-token"

RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]

3

API 게이트웨이와 함께 Lambda 통합 프록시를 사용하는 사람들을 위해 . 요청을 직접 제출하는 것처럼 람다 함수를 구성해야합니다. 즉, 함수가 응답 헤더를 올바르게 설정해야합니다. (커스텀 람다 함수를 사용하는 경우 API 게이트웨이에서 처리합니다.)

//In your lambda's index.handler():
exports.handler = (event, context, callback) => {
     //on success:
     callback(null, {
           statusCode: 200,
           headers: {
                "Access-Control-Allow-Origin" : "*"
           }
     }
}

1
또한 AWS 문서를 생각하지 않는 하나의 큰 문제를 언급하고 싶습니다. API 게이트웨이를 사용하여 람다 함수를 프록시하고 해당 람다 함수에서 일부 API를 사용한다고 가정하십시오. 해당 API가 200이 아닌 성공 성공 코드를 리턴하고 200이 아닌 성공 코드를 API 게이트웨이의 메소드 응답에 추가하지 않은 경우 오류가 표시되고 성공적인 응답이 표시되지 않습니다 . 이에 대한 예 : Sendgrid 및 Twilio에는 200이 아닌 성공 코드가 있습니다.
Stephen Tetreault

3

Chrome에서 CORS를 사용 중지하는 것은 좋은 방법이 아니라고 생각 합니다. 이온에서 사용하면 확실히 모바일 빌드에서 문제가 다시 발생하기 때문입니다.

백엔드에서 수정하는 것이 좋습니다.

먼저 In 헤더를 설정해야합니다.

  • 헤더 ( '액세스 제어 허용 원본 : *');
  • header ( '헤더 세트 액세스 제어 허용 헤더 : "원본, X-Requested-With, Content-Type, Accept"');

API가 GET 및 POST로 작동하는 경우 헤더에서 설정하십시오.

if ($ _SERVER [ 'REQUEST_METHOD'] == 'OPTIONS') {if (isset ($ _ SERVER [ 'HTTP_ACCESS_CONTROL_REQUEST_METHOD'])) header ( "Access-Control-Allow-Methods : GET, POST, OPTIONS");
if (isset ($ _ SERVER [ 'HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) header ( "액세스 제어 허용 헤더 :
{$ _SERVER [ 'HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}"); 이탈 (0); }


3

이 오류의 가장 일반적인 원인은 호스트 API가 요청을 http 메소드 (예 : PUT)에 맵핑했으며 API 클라이언트가 다른 http 메소드 (예 : POST 또는 GET)를 사용하여 API를 호출하고 있기 때문입니다.


나는 내 서버에서 제대로 CORS를 구현했지만, 난이 추가 깜빡 PUT방법
fguillen

3

우리 팀은 때때로 Vue, axios 및 C # WebApi를 사용하여이를 확인합니다. 적중하려는 엔드 포인트에 경로 속성을 추가하면 문제가 해결됩니다.

[Route("ControllerName/Endpoint")]
[HttpOptions, HttpPost]
public IHttpActionResult Endpoint() { }

왜 그런지 잘 모르겠습니다. 롤 누구든지 알려 주면!
w00ngy

1

DNS 서버가 8.8.8.8 (google)로 설정되었을 때이 문제에 직면했습니다. 실제로 문제는 라우터에 있었고 내 응용 프로그램은 로컬이 아닌 Google을 통해 서버와 연결하려고했습니다 (특정 경우). 8.8.8.8을 제거했으며 문제가 해결되었습니다. CORS 설정 으로이 문제가 해결되었지만 누군가 나와 같은 문제를 겪을 수 있음을 알고 있습니다.


1

업로드를 위해 AWS SDK를 사용하고 있습니다. 온라인 검색에 시간을 보낸 후이 스레드를 우연히 발견했습니다. @lsimoneau 45581857 덕분에 정확히 같은 일이 일어나고 있음 이 밝혀졌습니다. 리전 옵션을 첨부하여 내 요청 Url을 버킷의 리전으로 간단히 가리 켰습니다.

 const s3 = new AWS.S3({
 accessKeyId: config.awsAccessKeyID,
 secretAccessKey: config.awsSecretAccessKey,
 region: 'eu-west-2'  // add region here });

0

GeoServer 의 독립형 배포 에는 Jetty 응용 프로그램 서버가 포함됩니다. CORS (Cross-Origin Resource Sharing)를 활성화하면 도메인 외부의 JavaScript 애플리케이션이 GeoServer를 사용할 수 있습니다.

주석 다음 <filter><filter-mapping>웹 어플리케이션 / geoserver / WEB-INF / web.xml 파일에서 :

<web-app>
  <filter>
      <filter-name>cross-origin</filter-name>
      <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
  </filter>
  <filter-mapping>
      <filter-name>cross-origin</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

응답 헤더에 antyhing을 추가하지 않았으므로 작동하지 않았습니다.
JollyRoger

1
GeoServer를 사용하지 않지만이 클립을 사용하면 전화를받는 앱에서 사용해야하는 설정을 알 수있었습니다.
매트 펠 자니

0

아무 걱정없이 몇 단계 만 거치면이 문제를 쉽게 해결할 수 있습니다. 친절하게, 해결 단계를 수행하십시오.

  1. 오픈 ( https://www.npmjs.com/package/cors#enabling-cors-pre-flight )
  2. 설치로 이동하여 npm install cors 명령을 복사하여 노드 터미널을 통해 설치하십시오.
  3. 스크롤하여 Simple Usage (모든 CORS 요청 사용)로 이동 한 다음 ur 프로젝트에서 전체 선언을 복사하여 붙여 넣고 실행하십시오 ... 프로젝트를 시도하고 시도해보십시오.

1
var express = require ( 'express') var cors = require ( 'cors') var app = express () app.use (cors ()) app.get ( '/ products / : id', 함수 (req, res, 다음) {res.json ({msg : '이것은 모든 출처에서 CORS 가능!'})}) app.listen (80, function () {console.log ( '포트 80에서 CORS 가능 웹 서버 수신') )})
Rahul sah

-1

놓치기 매우 쉬운 것 ...

솔루션 탐색기에서 api-project를 마우스 오른쪽 단추로 클릭하십시오. 속성 창에서 '익명 인증'을 사용 함으로 설정하십시오 !!!


-8

크롬 보안을 비활성화합니다. 크롬 바로 가기를 마우스 오른쪽 버튼으로 클릭-> 속성-> 대상을 클릭 한 다음 "C : \ Program Files (x86) \ Google \ Chrome \ Application \ chrome.exe"붙여 넣기 --disable-web-security --user -data-dir = "c : / chromedev"

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