HP Alm의 REST API에서 일부 데이터를 가져 오려고합니다. 작은 curl 스크립트와 잘 작동합니다. 데이터를 얻습니다.
이제 JavaScript를 사용하여 가져 오는 것과 가져 오기 및 ES6 (더 많거나 적은)이 더 큰 문제인 것 같습니다. 이 오류 메시지가 계속 나타납니다.
Fetch API가로드 할 수 없습니다. 프리 플라이트 요청에 대한 응답이 액세스 제어 확인을 통과하지 못함 : 요청 된 리소스에 ‘Access-Control-Allow-Origin’헤더가 없습니다. 따라서 원본 ‘ http://127.0.0.1:3000 ‘은 액세스 할 수 없습니다. 응답의 HTTP 상태 코드는 501입니다. 불투명 한 응답이 사용자의 요구에 부응하는 경우 CORS가 비활성화 된 상태에서 리소스를 가져 오려면 요청 모드를 ‘no-cors’로 설정하십시오.
로컬 호스트 내에서 해당 데이터를 가져 오려고하기 때문에 솔루션이 CORS를 사용해야하기 때문에 이것이 이해됩니다. 이제 실제로 그렇게했다고 생각했지만 어떻게 든 헤더에 쓰는 것을 무시하거나 문제가 다른 것입니까?
그렇다면 구현 문제가 있습니까? 내가 잘못하고 있습니까? 불행히도 서버 로그를 확인할 수 없습니다. 나는 정말로 여기 붙어 있습니다.
function performSignIn() {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json');
headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
headers.append('Access-Control-Allow-Credentials', 'true');
headers.append('GET', 'POST', 'OPTIONS');
headers.append('Authorization', 'Basic ' + base64.encode(username + ":" + password));
fetch(sign_in, {
//mode: 'no-cors',
credentials: 'include',
method: 'POST',
headers: headers
})
.then(response => response.json())
.then(json => console.log(json))
.catch(error => console.log('Authorization failed : ' + error.message));
}
Chrome을 사용하고 있습니다. Chrome CORS 플러그인을 사용해 보았지만 다른 오류 메시지가 나타납니다.
요청의 자격 증명 모드가 ‘include’인 경우 응답의 ‘Access-Control-Allow-Origin’헤더 값이 와일드 카드 ‘*’가 아니어야합니다. 따라서 원본 ‘ http://127.0.0.1:3000 ‘은 액세스 할 수 없습니다. XMLHttpRequest에 의해 시작된 요청의 자격 증명 모드는 withCredentials 속성에 의해 제어됩니다.
답변
이 답변은 많은 근거를 다루므로 세 부분으로 나뉩니다.
- CORS 프록시를 사용하여 “No Access-Control-Allow-Origin header” 문제를 해결하는 방법
- CORS 프리 플라이트를 피하는 방법
- 어떻게 해결하는 “액세스 제어 – 허용 – 원산지 헤더는 와일드 카드가 아니어야합니다” 문제
CORS 프록시를 사용하여 “No Access-Control-Allow-Origin header” 문제를 해결하는 방법
프론트 엔드 JavaScript 코드가 요청을 보내는 서버를 제어하지 않고 해당 서버의 응답 문제가 필요한 Access-Control-Allow-Origin
헤더 가 부족한 경우 에도 요청을 통해 작업을 수행 할 수 있습니다. CORS 프록시. 작동 방식을 보여주기 위해 먼저 CORS 프록시를 사용하지 않는 코드가 있습니다.
const url = "https://example.com"; // site that doesn’t send Access-Control-*
fetch(url)
.then(response => response.text())
.then(contents => console.log(contents))
.catch(() => console.log("Can’t access " + url + " response. Blocked by browser?"))
catch
블록에 도달 하는 이유는 브라우저가 해당 코드가에서 오는 응답에 액세스하지 못하게하는 것입니다 https://example.com
. 그리고 브라우저가 그렇게하는 이유는 Access-Control-Allow-Origin
응답 헤더에 응답이 없기 때문 입니다.
이제 정확히 동일한 예이지만 CORS 프록시가 추가 된 것입니다.
const proxyurl = "https://cors-anywhere.herokuapp.com/";
const url = "https://example.com"; // site that doesn’t send Access-Control-*
fetch(proxyurl + url) // https://cors-anywhere.herokuapp.com/https://example.com
.then(response => response.text())
.then(contents => console.log(contents))
.catch(() => console.log("Can’t access " + url + " response. Blocked by browser?"))
참고 : https://cors-anywhere.herokuapp.com을 다운로드 할 때 다운되었거나 사용할 수없는 경우 2-3 분만에 Heroku에 자체 CORS Anywhere 서버를 배포하는 방법은 아래를 참조하십시오.
위의 두 번째 코드 스 니펫은 요청 URL을 가져 와서 프록시 URL을 접두사로 사용 하여 https://cors-anywhere.herokuapp.com/https://example.com으로 변경하기 때문에 응답에 성공적으로 액세스 할 수 있습니다 . 해당 프록시를 통해 요청하면 다음과 같습니다.
- 에 요청을 전달합니다
https://example.com
. - 에서 응답을받습니다
https://example.com
. Access-Control-Allow-Origin
응답에 헤더를 추가합니다 .- 추가 된 헤더와 함께 해당 응답을 요청 프론트 엔드 코드로 다시 전달합니다.
그런 다음 브라우저는 프론트 엔드 코드가 응답에 액세스 할 수있게합니다. Access-Control-Allow-Origin
응답 헤더가 있는 응답이 브라우저에 표시 되기 때문입니다 .
https://github.com/Rob–W/cors-anywhere/의 코드를 사용하여 자신의 프록시를 쉽게 실행할 수 있습니다 .
5 개의 명령으로 말 그대로 2-3 분만에 Heroku에 자신의 프록시를 쉽게 배포 할 수 있습니다.
git clone https://github.com/Rob--W/cors-anywhere.git
cd cors-anywhere/
npm install
heroku create
git push heroku master
해당 명령을 실행하면 https://cryptic-headland-94862.herokuapp.com/ 과 같은 자체 CORS Anywhere 서버가 실행됩니다 . 따라서 요청 URL 앞에 접두사를 붙이지 https://cors-anywhere.herokuapp.com
말고 대신 자신의 인스턴스 URL로 접두사를 붙이십시오 . 예를 들어, https://cryptic-headland-94862.herokuapp.com/https://example.com .
따라서 https://cors-anywhere.herokuapp.com을 사용하려고 할 때 다운되어 있음을 발견 한 경우 (아직 사용하지 않는 경우) Heroku 계정을 가져 와서 2를 가져 오는 것을 고려하십시오. 또는 3 분 동안 위 단계를 수행하여 Heroku에 자신의 CORS Anywhere 서버를 배포하십시오.
자체적으로 실행하든 https://cors-anywhere.herokuapp.com 또는 기타 개방형 프록시를 사용하든 상관없이이 솔루션은 브라우저가 CORS 프리 플라이트 OPTIONS
요청 을 수행하도록 브라우저를 트리거 하는 경우에도 작동합니다. 또한 프록시는 프리 플라이트를 성공적으로 수행하는 데 필요한 Access-Control-Allow-Headers
및 Access-Control-Allow-Methods
헤더를 다시 보냅니다 .
CORS 프리 플라이트를 피하는 방법
문제의 코드는 Authorization
헤더를 전송하기 때문에 CORS 프리 플라이트를 트리거합니다 .
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests
그것 없이도 Content-Type: application/json
헤더는 프리 플라이트를 트리거합니다.
무엇 “프리 플라이트”수단 : 브라우저가를 시도하기 전에 POST
문제의 코드에서, 그것은 먼저 보내드립니다 OPTIONS
서버에 요청을 – 크로스 기원 수신에 서버가 사용 중단 된 경우 결정 POST
포함 Authorization
하고 Content-Type: application/json
헤더를.
작은 curl 스크립트와 잘 작동합니다. 데이터를 얻습니다.
로 올바르게 테스트하려면 브라우저가 전송 curl
하는 프리 플라이트 OPTIONS
요청을 에뮬레이트해야합니다 .
curl -i -X OPTIONS -H "Origin: http://127.0.0.1:3000" \
-H 'Access-Control-Request-Method: POST' \
-H 'Access-Control-Request-Headers: Content-Type, Authorization' \
"https://the.sign_in.url"
… https://the.sign_in.url
실제 sign_in
URL이 무엇이든 대체됩니다 .
브라우저가 해당 OPTIONS
요청 에서 확인해야하는 응답 에는 다음과 같은 헤더가 포함되어야합니다.
Access-Control-Allow-Origin: http://127.0.0.1:3000
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Content-Type, Authorization
경우 OPTIONS
응답이 그 헤더를 포함하지 않는, 브라우저는 바로 거기 중지, 심지어 보내하지 마십시오 POST
요청을. 또한 응답의 HTTP 상태 코드는 2xx (일반적으로 200 또는 204) 여야합니다. 다른 상태 코드 인 경우 브라우저가 바로 중지됩니다.
문제의 서버 OPTIONS
가 501 상태 코드로 요청에 응답하고 있습니다. 이는 요청에 대한 지원을 구현하지 않음을 나타내는 것을 의미 OPTIONS
합니다. 이 경우 다른 서버는 일반적으로 405 “Method not allowed”상태 코드로 응답합니다.
따라서 POST
서버 OPTIONS
가 405 또는 501 또는 200 또는 204 이외의 다른 요청으로 해당 요청에 응답 하거나 필요한 응답으로 응답하지 않으면 프런트 엔드 JavaScript 코드에서 해당 서버로 직접 요청 을 할 수 없습니다. 응답 헤더.
문제의 사례에 대한 프리 플라이트를 유발하지 않는 방법은 다음과 같습니다.
- 서버가
Authorization
요청 헤더를 요구하지 않고 대신POST
요청 본문에 내장 된 인증 데이터 또는 쿼리 매개 변수에 의존 하는 경우 - 서버에
POST
본문에Content-Type: application/json
미디어 유형 이 필요하지 않지만 대신 JSON 데이터 값 을 갖는 매개 변수 (또는 기타)를 사용 하여POST
본문을 수락 한 경우application/x-www-form-urlencoded
json
어떻게 해결하는 “액세스 제어 – 허용 – 원산지 헤더는 와일드 카드가 아니어야합니다” 문제
다른 오류 메시지가 나타납니다.
요청의 자격 증명 모드가 ‘include’인 경우 응답의 ‘Access-Control-Allow-Origin’헤더 값이 와일드 카드 ‘*’가 아니어야합니다. 따라서 원본 ‘ http://127.0.0.1:3000 ‘은 액세스 할 수 없습니다. XMLHttpRequest에 의해 시작된 요청의 자격 증명 모드는 withCredentials 속성에 의해 제어됩니다.
자격 증명이 포함 된 요청의 경우 Access-Control-Allow-Origin
응답 헤더 값이 인 경우 브라우저에서 프런트 엔드 JavaScript 코드가 응답에 액세스 할 수 없습니다 *
. 대신이 경우의 값은 프론트 엔드 코드의 원점과 정확히 일치해야합니다 http://127.0.0.1:3000
.
참조 자격있는 요청과 와일드 카드 MDN이 HTTP 액세스 제어 (CORS) 기사를.
요청을 보내는 서버를 제어하는 경우이 경우를 처리하는 일반적인 방법은 Origin
요청 헤더 의 값을 가져 와서 Access-Control-Allow-Origin
응답 헤더 의 값으로 에코 / 반영하는 서버를 구성하는 것 입니다. 예를 들어, nginx의 경우 :
add_header Access-Control-Allow-Origin $http_origin
그러나 이것은 하나의 예일뿐입니다. 다른 (웹) 서버 시스템은 원점 값을 반향하는 유사한 방법을 제공합니다.
Chrome을 사용하고 있습니다. 또한 그 Chrome CORS 플러그인을 사용해 보았습니다.
Chrome CORS 플러그인 Access-Control-Allow-Origin: *
은 브라우저가 보는 응답에 헤더를 간단하게 삽입합니다 . 플러그인이 더 똑똑하다면, 가짜 Access-Control-Allow-Origin
응답 헤더 의 값을 프론트 엔드 JavaScript 코드의 실제 원점으로 설정하면 http://127.0.0.1:3000
됩니다.
따라서 테스트에도 플러그인을 사용하지 마십시오. 산만입니다. 브라우저에서 응답을 필터링하지 않고 서버에서 어떤 응답을 얻는 지 테스트하려면 curl -H
위와 같이 사용하는 것이 좋습니다 .
fetch(…)
질문 의 요청에 대한 프론트 엔드 JavaScript 코드까지 :
headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
headers.append('Access-Control-Allow-Credentials', 'true');
그 줄을 제거하십시오. Access-Control-Allow-*
헤더는 응답 헤더. 당신은 요청에 그들을 보내고 싶지 않습니다. 필요한 유일한 효과는 프리 플라이트를 수행하도록 브라우저를 트리거하는 것입니다.
답변
이 오류는 포트 번호를 포함하여 클라이언트 URL과 서버 URL이 일치하지 않을 때 발생합니다. 이 경우 교차 출처 자원 공유 인 CORS에 대해 서비스를 활성화해야합니다.
Spring REST 서비스를 호스팅하는 경우 Spring Framework 의 블로그 게시물 CORS 지원에서 찾을 수 있습니다 .
Node.js 서버를 사용하여 서비스를 호스팅하는 경우
- Node.js 서버를 중지하십시오.
npm install cors --save
-
server.js에 다음 줄을 추가하십시오.
var cors = require('cors') app.use(cors()) // Use this after the variable declaration
답변
프론트 엔드에서 요청 헤더 로 다음 코드를 추가했기 때문에 문제가 발생했습니다 .
headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
headers.append('Access-Control-Allow-Credentials', 'true');
이러한 헤더는 요청이 아닌 response 에 속합니다 . 따라서 라인을 포함하여 제거하십시오 .
headers.append('GET', 'POST', 'OPTIONS');
귀하의 요청에 ‘Content-Type : application / json’이 있었으므로 CORS 프리 플라이트가 트리거되었습니다. 이로 인해 브라우저가 OPTIONS 메소드로 요청을 보냈습니다. 자세한 내용은 CORS 프리 플라이트 를 참조하십시오.
따라서 백엔드 에서는 다음을 포함하는 응답 헤더를 반환하여이 프리 플라이트 요청을 처리해야합니다.
Access-Control-Allow-Origin : http://localhost:3000
Access-Control-Allow-Credentials : true
Access-Control-Allow-Methods : GET, POST, OPTIONS
Access-Control-Allow-Headers : Origin, Content-Type, Accept
물론 실제 구문은 백엔드에 사용하는 프로그래밍 언어에 따라 다릅니다.
프런트 엔드에서는 다음과 같아야합니다.
function performSignIn() {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json');
headers.append('Authorization', 'Basic ' + base64.encode(username + ":" + password));
headers.append('Origin','http://localhost:3000');
fetch(sign_in, {
mode: 'cors',
credentials: 'include',
method: 'POST',
headers: headers
})
.then(response => response.json())
.then(json => console.log(json))
.catch(error => console.log('Authorization failed : ' + error.message));
}
답변
내 경우에는 아래 솔루션을 사용합니다.
프런트 엔드 또는 앵귤러
post(
this.serverUrl, dataObjToPost,
{
headers: new HttpHeaders({
'Content-Type': 'application/json',
})
}
)
백엔드 (PHP를 사용합니다)
header("Access-Control-Allow-Origin: http://localhost:4200");
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header("Access-Control-Allow-Headers: Content-Type, Authorization");
$postdata = file_get_contents("php://input");
$request = json_decode($postdata);
print_r($request);
답변
CORS 프록시를 사용하여“ 헤더 없음 ”문제를 해결 하는 방법에 관한 2 센트Access-Control-Allow-Origin
백엔드에서 PHP로 작업하는 사람들을 위해 “CORS 프록시”를 배포하는 것은 다음과 같이 간단합니다.
-
다음 내용으로 ‘no-cors.php’라는 파일을 만듭니다.
$URL = $_GET['url'];
echo json_encode(file_get_contents($URL));
die(); -
프론트 엔드에서 다음과 같이하십시오.
fetch('https://example.com/no-cors.php' + '?url=' + url)
.then(response=>{*/Handle Response/*})
답변
이것을 제거하십시오 :
credentials: 'include',
답변
사용하는 dataType: 'jsonp'
날 위해 일했습니다.
async function get_ajax_data(){
var _reprojected_lat_lng = await $.ajax({
type: 'GET',
dataType: 'jsonp',
data: {},
url: _reprojection_url,
error: function (jqXHR, textStatus, errorThrown) {
console.log(jqXHR)
},
success: function (data) {
console.log(data);
// note: data is already json type, you
// just specify dataType: jsonp
return data;
}
});
} // function