[javascript] JavaScript 코드에서 Postman에 “요청 된 자원에 ‘Access-Control-Allow-Origin’헤더가 없습니다”오류가 표시되지 않는 이유는 무엇입니까?

Mod note :이 질문은 Postman이 XMLHttpRequest와 같은 방식으로 CORS 제한을받지 않는 이유에 관한 것입니다. 이 질문은 “No ‘Access-Control-Allow-Origin’…”오류를 수정하는 방법 이 아닙니다 .

게시를 중지하십시오 :


RESTful API 내장 Flask 에 연결 하여 JavaScript 를 사용하여 권한 부여를 시도하고 있습니다. 그러나 요청하면 다음 오류가 발생합니다.

XMLHttpRequest가 http : // myApiUrl / login을 로드 할 수 없습니다 . 요청 된 리소스에 ‘Access-Control-Allow-Origin’헤더가 없습니다. 따라서 원점 ‘널’은 액세스가 허용되지 않습니다.

API 또는 원격 리소스가 헤더를 설정해야한다는 것을 알고 있지만 Chrome 확장 프로그램 Postman을 통해 요청했을 때 왜 작동 했 습니까?

이것은 요청 코드입니다.

$.ajax({
    type: "POST",
    dataType: 'text',
    url: api,
    username: 'user',
    password: 'pass',
    crossDomain : true,
    xhrFields: {
        withCredentials: true
    }
})
    .done(function( data ) {
        console.log("done");
    })
    .fail( function(xhr, textStatus, errorThrown) {
        alert(xhr.responseText);
        alert(textStatus);
    });



답변

내가 올바르게 이해하면 귀하의 페이지가 아닌 다른 도메인에 XMLHttpRequest 를하고 있습니다. 따라서 브라우저는 일반적으로 보안상의 이유로 동일한 출처에서 요청을 허용하므로 브라우저를 차단합니다. 도메인 간 요청을 수행하려는 경우 다른 작업을 수행해야합니다. 이를 달성하는 방법에 대한 튜토리얼은 Using CORS 입니다.

우편 배달부를 사용하는 경우이 정책에 의해 제한되지 않습니다. Cross-Origin XMLHttpRequest 에서 인용 :

일반 웹 페이지는 XMLHttpRequest 객체를 사용하여 원격 서버와 데이터를주고받을 수 있지만 동일한 원본 정책에 의해 제한됩니다. 확장은 그렇게 제한되지 않습니다. 교차 출처 권한을 먼저 요청하는 한 확장은 원래 외부의 원격 서버와 통신 할 수 있습니다.


답변

경고 :를 사용하면 Access-Control-Allow-Origin: *API / 웹 사이트가 CSRF ( Cross-Site Request Forgery) 공격에 취약해질 수 있습니다. 이 코드를 사용하기 전에 위험이해 했는지 확인하십시오 .

PHP를 사용하는 경우 해결하는 것이 매우 간단합니다 . 요청을 처리하는 PHP 페이지의 시작 부분에 다음 스크립트를 추가하십시오.

<?php header('Access-Control-Allow-Origin: *'); ?>

Node-red 를 사용 하는 경우 다음 행을 주석 해제 하여 파일 에서 CORS 를 허용해야합니다 node-red/settings.js.

// The following property can be used to configure cross-origin resource sharing
// in the HTTP nodes.
// See https://github.com/troygoode/node-cors#configuration-options for
// details on its contents. The following is a basic permissive set of options:
httpNodeCors: {
 origin: "*",
 methods: "GET,PUT,POST,DELETE"
},

Flask 를 사용 하는 경우 질문과 동일합니다. 먼저 설치해야합니다flask-cors

$ pip install -U flask-cors

그런 다음 응용 프로그램에 Flask cors를 포함하십시오.

from flask_cors import CORS

간단한 응용 프로그램은 다음과 같습니다.

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

@app.route("/")
def helloWorld():
  return "Hello, cross-origin-world!"

자세한 내용은 Flask 설명서를 확인할 수 있습니다 .


답변

때문에
$ 아약스 ({유형 : “POST”는 – 통화 옵션
$이 (.post 호출 – POST를

둘 다 다릅니다. 우편 배달부에서는 “POST”를 올바르게 호출하지만 전화를 걸면 “OPTIONS”가됩니다.

C # 웹 서비스의 경우- 웹 API

<system.webServer> 태그 아래 web.config 파일에 다음 코드를 추가하십시오 . 이것은 작동합니다 :

<httpProtocol>
    <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
    </customHeaders>
</httpProtocol>

Ajax 호출에서 실수하지 않도록하십시오

jQuery

$.ajax({
    url: 'http://mysite.microsoft.sample.xyz.com/api/mycall',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    type: "POST", /* or type:"GET" or type:"PUT" */
    dataType: "json",
    data: {
    },
    success: function (result) {
        console.log(result);
    },
    error: function () {
        console.log("error");
    }
});

참고 : 당신이 콘텐츠를 다운로드를 찾고 있다면 타사 웹 사이트에서 다음 이 도움이되지 않습니다 . 다음 코드는 시도 할 수 있지만 JavaScript는 시도 할 수 없습니다.

System.Net.WebClient wc = new System.Net.WebClient();
string str = wc.DownloadString("http://mysite.microsoft.sample.xyz.com/api/mycall");


답변

CORS 제한 적용은 서버에 의해 정의되고 브라우저에 의해 구현되는 보안 기능 입니다.

브라우저는 서버의 CORS 정책을보고 존중합니다.

그러나 Postman 도구는 서버의 CORS 정책을 신경 쓰지 않습니다.

이것이 CORS 오류가 브라우저에 나타나지만 Postman에는 나타나지 않는 이유입니다.


답변

아래의 API로 조사 할 때 귀하의 질문 에 http : // myApiUrl / login 대신 http://example.com을 사용 합니다.

귀하의 페이지가 http : //my-site.local : 8088 에 있다고 가정합니다 .

다른 결과를 보는 이유는 다음과 같습니다.

  • 헤더 설정 Host=example.com(API)
  • 헤더를 설정하지 않았습니다 Origin

이것은 사이트와 API가 동일한 도메인을 가질 때 브라우저가 요청을 보내는 방법과 유사합니다 (브라우저도 헤더 항목을 설정 Referer=http://my-site.local:8088하지만 Postman에서는 보이지 않습니다). Origin헤더가되어 있지 설정, 일반적으로 서버는 기본적으로 이러한 요청을 할 수 있습니다.

여기에 이미지 설명을 입력하십시오

이것은 Postman이 요청을 보내는 표준 방법입니다. 그러나 사이트와 API의 도메인이 다른 경우 브라우저가 요청을 다르게 보낸 다음 CORS 가 발생하고 브라우저가 자동으로 다음을 수행합니다.

  • 헤더를 설정합니다 Host=example.com(귀하의 API로)
  • 헤더를 설정합니다 Origin=http://my-site.local:8088(귀하의 사이트)

(헤더 Referer의 값 은와 동일합니다 Origin). 이제 Chrome의 콘솔 및 네트워크 탭에 다음이 표시됩니다.

여기에 이미지 설명을 입력하십시오

여기에 이미지 설명을 입력하십시오

당신이있을 때 Host != Origin그것을 일반적으로이 CORS이며, 서버는 이러한 요청을 감지 할 때 기본적으로 블록을 .

Origin=null로컬 디렉토리에서 HTML 컨텐츠를 열 때 설정되며 요청을 보냅니다. 같은 상황은 <iframe>아래 스 니펫과 같이 내부에 요청을 보낼 때입니다 (그러나 여기에는 Host헤더가 전혀 설정되어 있지 않습니다). 일반적으로 HTML 사양이 불투명 원점을 말하는 모든 곳에서로 변환 할 수 있습니다 Origin=null. 이에 대한 자세한 내용은 여기를 참조하십시오 .

fetch('http://example.com/api', {method: 'POST'});
Look on chrome-console > network tab

간단한 CORS 요청을 사용하지 않는 경우 일반적으로 브라우저는 기본 요청을 보내기 전에 OPTIONS 요청을 자동으로 보냅니다 . 자세한 정보는 여기에 있습니다 . 아래 스 니펫은 다음과 같습니다.

fetch('http://example.com/api', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json'}
});
Look in chrome-console -> network tab to 'api' request.
This is the OPTIONS request (the server does not allow sending a POST request)

CORS 요청을 허용하도록 서버 구성을 변경할 수 있습니다.

다음은 nginx (nginx.conf 파일) 에서 CORS를 설정하는 구성 예 always/"$http_origin"입니다. nginx 및 "*"Apache 설정 에 매우주의 하십시오. 그러면 모든 도메인에서 CORS가 차단 해제됩니다.

다음은 Apache (.htaccess 파일) 에서 CORS를 설정하는 구성 예입니다.


답변

다른 사용 사례에서 동일한 오류가 발생했습니다.

유스 케이스 : 크롬에서 Spring REST 엔드 포인트를 각도 로 호출하려고 할 때 크롬 에서.

여기에 이미지 설명을 입력하십시오

해결 방법 : 각 컨트롤러 클래스 위에 @CrossOrigin ( “*”) 주석을 추가하십시오 .

여기에 이미지 설명을 입력하십시오


답변

.NET을 중간 계층으로 사용하는 경우 경로 속성을 명확하게 확인하십시오 (예 :

이럴 때 문제가 있었어요

[Route("something/{somethingLong: long}")] //Space.

이것으로 고쳤습니다.

[Route("something/{somethingLong:long}")] //No space