요청 헤더 필드 Access-Control-Allow-Headers는 프리 플라이트 응답에서 자체적으로 허용되지 않습니다.


234

CORS 문제를 여러 번 발견했으며 일반적으로 해결할 수 있지만 MEAN 스택 패러다임 에서이 문제를 확인하여 실제로 이해하고 싶습니다.

Express 서버에 미들웨어를 추가하여 이러한 것들을 포착하기 전에 요청에 오류가 발생하는 일종의 사전 후크가있는 것 같습니다.

요청 헤더 필드 Access-Control-Allow-Headers는 프리 플라이트 응답의 Access-Control-Allow-Headers에서 허용되지 않습니다.

나는 이것을 할 수 있다고 가정했다.

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Headers","*")
})

또는 동등한 것이지만 이것은 수정하지 않는 것 같습니다. 나는 또한 시도했다

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Headers","Access-Control-Allow-Headers")
})

아직 운이 없다.

답변:


245

사용자 정의 요청 헤더로 게임을 시작하면 CORS 프리 플라이트가 제공됩니다. 이것은 HTTP OPTIONS동사 를 사용하는 요청 이며 여러 헤더를 포함하며 그 중 하나 Access-Control-Request-Headers는 클라이언트가 요청에 포함하려는 헤더를 나열합니다.

이 작업을 수행하려면 적절한 CORS 헤더를 사용하여 해당 CORS 프리 플라이트에 응답해야합니다. 그 중 하나는 실제로 Access-Control-Allow-Headers입니다. 해당 헤더에는 헤더에 포함 된 값 Access-Control-Request-Headers(또는 그 이상)이 포함되어야합니다.

https://fetch.spec.whatwg.org/#http-cors-protocol 에서이 설정에 대해 자세히 설명합니다.


41
Chrome을 사용 중이고 어떤 헤더가 요청되는지 확실하지 않은 경우 개발자 콘솔을 사용하여 네트워크에서 전화를 걸고 요청한 헤더를 볼 수 있습니다.Access-Control-Request-Headers
Lionel Morrison

5
개발자 콘솔 옵션이 좋습니다. 서버의 요청 오브젝트에 액세스하여 헤더 값, 특히 "Access-Control-Request-Headers"헤더 값을 덤프하여 필요한 것을 찾을 수도 있습니다. 그런 다음 이것을 response.setHeader ( "Access-Control-Allow-Headers", "{paste here}")에 복사 / 붙여 넣기
Software Prophets

7
예를 들어주세요!
Demodave

5
@Demodave 저의 예는 다음과 같습니다header("Access-Control-Allow-Headers: Content-Type")
Joshua Duxbury

1
@LionelMorrison, 헤더 일치를 위해 크롬 개발 도구 사용. 잘 설명했다 !!!
Savina Chandla

119

이것이 작동하려면 추가해야합니다.

response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
response.setHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");

브라우저는 서버에서 호스팅되는 서비스가 다른 도메인의 브라우저에서 액세스 될 수 있는지 확인하기 위해 프리 플라이트 요청 (메소드 유형 OPTIONS 포함)을 보냅니다. 프리 플라이트 요청에 응답하여 위의 헤더를 삽입하면 브라우저는 추가 전화를 걸면 괜찮다는 것을 이해하고 실제 GET / POST 전화에 유효한 응답을 얻습니다. * 대신에 Access-Control-Allow-Origin ","localhost, xvz.com "을 사용하여 액세스 권한이 부여 된 도메인을 제한 할 수 있습니다. (*는 모든 도메인에 대한 액세스 권한을 부여합니다)


7
당신은 결합 할 수 없습니다 *위해 ...-Origintrue위해 ...-Credentials. 자격 증명이 아닌 요청에 대해서는 실패하지 않지만 자격 증명 요청에 대해서도 작동하지 않습니다. 내 답변에 게시 된 링크를 참조하십시오.
Anne

Manish Arora에게 감사합니다. 귀하의 솔루션을 API에 사용했는데 효과가있었습니다. HttpContext.Response.Headers.Add ( "액세스 제어 허용 방법", "GET, HEAD, OPTIONS, POST, PUT"); HttpContext.Response.Headers.Add ( "Access-Control-Allow-Headers", "Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access (액세스 제어 허용 헤더)" -제어 요청 헤더 "); HttpContext.Response.Headers.Add ( "Access-Control-Allow-Origin", " localhost : 4200" );
Ramakrishnankt

1
이것은 "프리 플라이트"때문에 서버 측에서이 응답 헤더를 모두 제거해야한다고 말하는 것입니까? 왜? 특히 완벽한 표준 헤더? 한동안 HTTP를 사용한 것은 많은 상용구가 필요하다는 소식입니다.
사만다 앳킨스

@manish 나는 작동하지 않는 Access-Control-Allow-Headers에 대해 다른 값 세트를 가지고있었습니다. 당신의 가치관이 그랬습니다. 시간과 좌절을 주셔서 감사합니다.
azakgaim

헤더를 와일드 카드하는 방법이 있습니까? 모든 헤더를 와일드 카드하는 것은 나쁜 생각입니까? 같은 response.setHeader("Access-Control-Allow-Headers", "*")? 이 작업의 보안 의미는 무엇입니까?
Vadorequest

78

이 문제는

 "Origin, X-Requested-With, Content-Type, Accept, Authorization"

내 프로젝트의 특정 (express.js / nodejs)

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
  next();
});

최신 정보:

매번 오류 : Access-Control-Allow-Headers is not allowed by itself in preflight response오류 당신은 크롬 개발자 도구에 어떤 문제가 있는지 볼 수 있습니다 :
여기에 이미지 설명을 입력하십시오

위의 오류가 Content-Type없으므로 문자열 Content-Type을 추가하십시오.Access-Control-Allow-Headers


1
모든 사람에게 적용되지는 않습니다. Access-Control-Request-Headers의 값은 환경에 따라 달라질 수 있습니다. 서버에서 요청 오브젝트에 액세스하고 "Access-Control-Request-Headers"헤더의 값을 덤프하십시오. 그런 다음 이것을 response.setHeader ( "Access-Control-Allow-Headers", "{paste here}")에 복사 / 붙여 넣기
Software Prophets

1
또한 영국식 방식이 아닌 미국식 방식으로 권한을 부여해야합니다. 내 인생의 반 시간은 내가 돌아 오지 않을 것입니다. Thx USA! [sigh]
geoidesic

14

받아 들여진 대답은 괜찮지 만 이해하기가 어려웠습니다. 다음은이를 명확히하는 간단한 예입니다.

내 아약스 요청에 표준 인증 헤더가있었습니다.

$$(document).on('ajaxStart', function(e){
var auth_token = localStorage.getItem(SB_TOKEN_MOBILE);
if( auth_token ) {
    var xhr = e.detail.xhr;

    xhr.setRequestHeader('**Authorization**', 'Bearer ' + auth_token);
}

이 코드는 문제의 오류를 생성합니다. nodejs 서버에서해야 할 일은 허용 된 헤더에 권한 부여를 추가하는 것이 었습니다.

res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type,**Authorization**');

6

다른 답변에 추가하십시오. 나는 같은 문제가 있었고 이것은 REST 호출을 허용하기 위해 Express 서버에서 사용한 코드입니다.

app.all('*', function(req, res, next) {
  res.header('Access-Control-Allow-Origin', 'URLs to trust of allow');
  res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
  res.header('Access-Control-Allow-Headers', 'Content-Type');
  if ('OPTIONS' == req.method) {
  res.sendStatus(200);
  } else {
    next();
  }
});

이 코드는 기본적으로 모든 요청을 가로 채고 CORS 헤더를 추가 한 다음 정상적인 경로를 계속 사용합니다. OPTIONS 요청이 있으면 CORS 헤더로만 응답합니다.

편집 : 동일한 컴퓨터에서 두 개의 별도 nodejs Express 서버 에이 수정 프로그램을 사용하고있었습니다. 결국 간단한 프록시 서버로 문제를 해결했습니다.


감사! 간단한 프록시 서버를 어떻게 사용했는지 자세히 설명해 주시겠습니까?
austin_ce

5

방금 ASP.NET 컨텍스트에서 Web.config가 다음과 같은지 확인하십시오.

  <system.webServer>
<modules>
  <remove name="FormsAuthentication" />
</modules>

<handlers>
  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
  <!--<remove name="OPTIONSVerbHandler"/>-->
  <remove name="TRACEVerbHandler" />
  <!--
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
  -->
</handlers>

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Headers" value="Content-Type, Authorization" />
    <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
  </customHeaders>
</httpProtocol>

Access-Control-Allow-Headers키 의 Authorization 값을 확인하십시오 . 권한 부여 값이 누락되었습니다.이 구성으로 문제가 해결됩니다.


5

실 렉스 프로젝트에서 이것을 사용했습니다.

$app->after(function (Request $request, Response $response) {
        $response->headers->set('Access-Control-Allow-Origin', '*');
        $response->headers->set("Access-Control-Allow-Credentials", "true");
        $response->headers->set("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
        $response->headers->set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
    });

2
이 코드는 질문에 대답 할 수 있지만 문제를 해결하는 방법 및 / 또는 이유에 대한 추가 컨텍스트를 제공하면 답변의 장기적인 가치가 향상됩니다.
Badacadabra 2016 년

4

Chrome에서 :

프리 플라이트 응답에서 Access-Control-Allow-Headers는 요청 헤더 필드 X-Requested-With를 사용할 수 없습니다.

나 에게이 오류는 이 호출의 URL에서 후행 공백 으로 인해 발생했습니다 .

jQuery.getJSON( url, function( response, status, xhr ) {
   ...
}

3

추가하기 위해 헤더를 Webpack 구성 파일에도 넣을 수 있습니다. webpack dev 서버를 실행할 때 필자의 경우와 같이 필요했습니다.

devServer: {
    headers: {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Credentials": "true",
      "Access-Control-Allow-Methods": "GET,HEAD,OPTIONS,POST,PUT",
      "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept, Authorization"
},


2

Django, React 및 django-cors-headers lib를 사용하여 OP가 언급 한 오류를 받았습니다. 이 스택으로 수정하려면 다음을 수행하십시오.

settings.py에서 공식 문서에 따라 아래를 추가하십시오 .

from corsheaders.defaults import default_headers

CORS_ALLOW_HEADERS = default_headers + (
'YOUR_HEADER_NAME',
)

2

이 문제는 요청에 대한 사용자 지정 헤더를 만들 때 발생합니다 HTTP OPTIONS.

이 요청에 필요한 헤더는 Access-Control-Request-Headers입니다. 응답 헤더의 일부 여야하며 모든 출처의 요청을 허용해야합니다. 때로는 Content-Type응답 헤더에도 필요합니다 . 응답 헤더는 다음과 같아야합니다.

response.header("Access-Control-Allow-Origin", "*"); // allow request from all origin
response.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
response.header("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin, X-Requested-With, Content-Type, Accept, Authorization");

1

Post API 호출에서 요청 본문에 데이터를 전송합니다. 따라서 API 호출에 헤더를 추가하여 데이터를 보내면됩니다. 그런 다음 먼저 OPTIONS API 호출이 발생한 후 사후 호출이 발생합니다. 따라서 먼저 OPTION API 호출을 처리해야합니다.

필터를 작성하고 옵션 호출 API 호출을 확인하고 200 OK 상태를 반환해야하는 문제를 처리 할 수 ​​있습니다. 다음은 샘플 코드입니다.

package com.web.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.catalina.connector.Response;

public class CustomFilter implements Filter {
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest httpRequest = (HttpServletRequest) req;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with, Content-Type");
        if (httpRequest.getMethod().equalsIgnoreCase("OPTIONS")) {
            response.setStatus(Response.SC_OK);
        }
        chain.doFilter(req, res);
    }

    public void init(FilterConfig filterConfig) {
        // TODO
    }

    public void destroy() {
        // Todo
    }

}

1

요청 헤더에 사용자 정의 헤더를 추가하려는 경우 특정 헤더가 허용됨을 서버에 알려야합니다. 그 장소는 요청을 필터링하는 클래스에 있습니다. 아래에 표시된 예에서 사용자 정의 헤더 이름은 "type"입니다.

public class CorsFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin",  request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,PATCH,OPTIONS");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me, Authorization, type ");
        response.setHeader("Access-Control-Expose-Headers","Authorization");
    }
}

1

거의 하루를 보낸 후 방금 아래 두 코드를 추가하면 문제가 해결되었음을 알았습니다.

Global.asax에 이것을 추가하십시오

protected void Application_BeginRequest()
{
  if (Request.HttpMethod == "OPTIONS")
  {
    Response.StatusCode = (int)System.Net.HttpStatusCode.OK;             
    Response.End();
  }
}

웹 설정에서 아래를 추가하십시오.

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />        
    <add name="Access-Control-Allow-Methods" value="*" />
    <add name="Access-Control-Allow-Headers" value="Content-Type, Authorization" />
  </customHeaders>
</httpProtocol>

1

Angular 6에서도 동일한 문제에 직면했습니다. 아래 코드를 사용하여 문제를 해결했습니다. component.ts 파일에 코드를 추가하십시오.

import { HttpHeaders } from '@angular/common/http';

headers;

constructor() {
    this.headers = new HttpHeaders();
    this.headers.append('Access-Control-Allow-Headers', 'Authorization');
}

getData() {
    this.http.get(url,this.headers). subscribe (res => {
    // your code here...
})}

0

내가 겪었던 동일한 문제.

나는 간단한 변화를했다.

  <modulename>.config(function($httpProvider){
    delete $httpProvider.defaults.headers.common['X-Requested-With'];
});

0

API에서 '인증'이 허용되지 않는다는 메시지가 분명합니다. 설정
액세스 제어 - 허용 - 헤더 : "Content-Type을, 권한 부여"


0
const express = require('express')
const cors = require('cors')
const app = express()

app.get('/with-cors', cors(), (req, res, next) => {
  res.json({ msg: 'WHOAH with CORS it works! 🔝 🎉' })
})

get 함수에 cors 추가 나를 위해 일한 것은 무엇입니까?

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