HTML5 가져 오기 API를 사용하여 Access-Control-Allow-Origin 헤더 허용


87

HTML5 가져 오기 API를 사용하고 있습니다.

var request = new Request('https://davidwalsh.name/demo/arsenal.json');

fetch(request).then(function(response) {
    // Convert to JSON
    return response.json();
}).then(function(j) {
    // Yay, `j` is a JavaScript object
    console.log(JSON.stringify(j));
}).catch(function(error) {
    console.log('Request failed', error)
});

일반 json을 사용할 수 있지만 위의 api url의 데이터를 가져올 수 없습니다. 오류가 발생합니다.

Fetch API는 https://davidwalsh.name/demo/arsenal.json을 로드 할 수 없습니다 . 요청 된 리소스에 'Access-Control-Allow-Origin'헤더가 없습니다. 따라서 원본 ' http : // localhost '는 액세스가 허용되지 않습니다. 불투명 한 응답이 요구 사항을 충족하는 경우 요청 모드를 'no-cors'로 설정하여 CORS가 비활성화 된 리소스를 가져옵니다.


타사 서버에서 설정해야하며 클라이언트 측에서 할 수있는 작업이 없습니다.
epascarello

@epascarello : 클라이언트 측에서 할 수 있습니다. 이면에서 XHR 요청이 진행됩니다. 이것을 확인하십시오https://davidwalsh.name/fetch
iNikkz

답변:


81

epascarello가 말했듯이 리소스를 호스팅하는 서버는 CORS를 활성화해야합니다. 클라이언트 측에서 할 수있는 작업 (그리고 아마도 생각하고있는 것)은 CORS로 가져 오기 모드를 설정하는 것입니다 (내가 생각하는 기본 설정 임에도 불구하고).

fetch(request, {mode: 'cors'});

그러나이 여전히 자원을 요청하는 도메인을뿐만 아니라 CORS를 활성화하고 허용하는 서버가 필요합니다.

CORS 문서동일한 출처 정책을 설명하는 이 멋진 Udacity 비디오를 확인하십시오 .

클라이언트 측에서 no-cors 모드를 사용할 수도 있지만 이것은 불투명 한 응답을 제공합니다 (본문을 읽을 수는 없지만 응답은 여전히 ​​서비스 워커가 캐시하거나 일부 API에서 사용할 수 <img>있습니다. :

fetch(request, {mode: 'no-cors'})
.then(function(response) {
  console.log(response); 
}).catch(function(error) {  
  console.log('Request failed', error)  
});

2
"하지만 여전히 서버가 CORS를 활성화하고 도메인이 리소스를 요청하도록 허용해야합니다."에 대해 자세히 설명 할 수 있습니까? 나는 그것을 수행하는 지침을 찾지 못했습니다.
jayscript

2
@jayscript 전체 프로세스는 다음과 같습니다. 클라이언트에서 javascript로 교차 원본 요청이 이루어집니다. fetch API의 경우 'cors'모드는 브라우저에이 요청을 할 수 있음을 알려줍니다. 대신 'no-cors'모드가있는 경우 앱의 출처가 아니기 때문에 브라우저가 요청을 중지합니다. 서버는 요청을 받고 응답합니다. 브라우저 응답이 적절한 CORS 헤더를 가지고 있으며, 만약 그렇다면, 응답을 읽을 할 수 있는지 확인한다. 헤더가 없으면 브라우저에서 오류가 발생합니다.
David Scales

1
@jayscript 이 MDN 기사 에 대해 자세히 설명합니다. 기본적으로 서버에 다음 헤더를 설정해야합니다. "Access-Control-Allow-Origin : foo.example ", "Access-Control-Allow-Methods : POST, GET, OPTIONS", "Access-Control-Allow-Headers : X-PINGOTHER, Content-Type "은 각각 출처, 메소드 및 헤더를 활성화합니다. 일반적으로 원본 헤더에는 '*'가 사용됩니다. 또한이 Google 문서 및 관련 코드 랩을 확인하여 Fetch API에 대해 알아볼 수 있습니다. developers.google.com/web/ilt/pwa/working-with-the-fetch-api
David Scales

2
감사합니다! API 서버에 헤더가없는 경우 출처가 다른 API 서버에서 데이터를 가져올 수 없다는 것을 이해하는 데 도움이됩니다. 내가 다루는 특별한 경우에는 API 서버 코드에 액세스 할 수 있었고 직접 헤더를 추가 할 수있어 가져 오기가 가능했습니다.
jayscript

이것은 바보입니다. NO sending쿠키 의 보안 문제는 무엇 이며 따라서 CORS를 허용합니까?
deathangel908

14

http : // localhost : 3000 에서 실행중인 프런트 엔드 코드 와 http : // localhost : 5000 에서 실행중인 API (백엔드 코드)가 있습니다 .

가져 오기 API를 사용하여 API를 호출했습니다. 처음에는 "cors"오류가 발생했습니다. 그런 다음 백엔드 API 코드에 아래 코드를 추가하여 어디서나 출처와 헤더를 허용합니다.

let allowCrossDomain = function(req, res, next) {
  res.header('Access-Control-Allow-Origin', "*");
  res.header('Access-Control-Allow-Headers', "*");
  next();
}
app.use(allowCrossDomain);

그러나 stage, prod와 같은 다른 환경의 경우 원본을 제한해야합니다.


20
이것은 끔찍한 대답입니다. 이것은 엄청난 보안 문제입니다. 당신이 이것을 읽고 있다면, 이것을하지 마십시오.
mjones.udri

1
이것은 로컬 설정을위한 것입니다. 예를 들어 약간의 빠른 그림을 수행합니다. 예, 다른 배포 가능한 환경에서도 마찬가지 일 경우 보안 위험이 있습니다. 지역을 위해 나는 그렇지 않은 느낌 "당신이 자극 단계와 같은 다른 환경의 경우에 당신 기원을 제한해야하지만."
smsivaprakaash

12

이것은 나를 위해 일했습니다.

npm install -g local-cors-proxy

CORS 문제가있는 요청하려는 API 엔드 포인트 :

https://www.yourdomain.com/test/list

프록시 시작 :

lcp --proxyUrl https://www.yourdomain.com

 Proxy Active 

 Proxy Url: http://www.yourdomain.com:28080
 Proxy Partial: proxy
 PORT: 8010

그런 다음 클라이언트 코드에서 새 API 엔드 포인트 :

http://localhost:8010/proxy/test/list

최종 결과는 CORS 문제없이 https://www.yourdomain.ie/test/list에 대한 요청입니다 !


Pls는 서버가 병렬로 실행되고 있는지 확인합니다. 새 cmt-prompt 창을 열고 lcp --proxyUrl yourdomain.com
Govarthanan Venunathan

8

나는 이것이 오래된 게시물이라는 것을 알고 있지만이 오류를 수정하는 데 도움이 된 것은 가져 오기 요청에서 도메인 이름을 사용하는 대신 서버의 IP 주소를 사용하는 것입니다. 예를 들면 다음과 같습니다.

#(original) var request = new Request('https://davidwalsh.name/demo/arsenal.json');
#use IP instead
var request = new Request('https://0.0.0.0/demo/arsenal.json');

fetch(request).then(function(response) {
    // Convert to JSON
    return response.json();
}).then(function(j) {
    // Yay, `j` is a JavaScript object
    console.log(JSON.stringify(j));
}).catch(function(error) {
    console.log('Request failed', error)
});

1

nginx를 사용하는 경우 이것을 시도하십시오

#Control-Allow-Origin access

    # Authorization headers aren't passed in CORS preflight (OPTIONS) calls. Always return a 200 for options.
    add_header Access-Control-Allow-Credentials "true" always;
    add_header Access-Control-Allow-Origin "https://URL-WHERE-ORIGIN-FROM-HERE " always;
    add_header Access-Control-Allow-Methods "GET,OPTIONS" always;
    add_header Access-Control-Allow-Headers "x-csrf-token,authorization,content-type,accept,origin,x-requested-with,access-control-allow-origin" always;

    if ($request_method = OPTIONS ) {
        return 200;
    }


-3

https://expressjs.com/en/resources/middleware/cors.html을 보십시오 . cors를 사용해야합니다.

설치:

$ npm install cors
const cors = require('cors');
app.use(cors());

이 코드를 노드 서버에 넣어야합니다.


1
OP의 서버이고 NodeJ로 작성되었는지 어떻게 알 수 있습니까?
Marek Szkudelski

노드 서버 (개발 모드)를 만든 경우 해당 메서드를 사용하여 js에서 가져 오기를 사용할 수 있습니다.
Ernersto Pastori
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.