JavaScript 코드에 "No 'Access-Control-Allow-Origin' 헤더는 요청된 리소스에 있습니다" 오류가 표시되지만 Postman은 표시되지 않는 이유는 무엇입니까?
Mod 노트:이 질문은 왜?
XMLHttpRequest
/fetch
브라우저의 /etc는 동일한 접근정책 제한(CORB 또는 CORS에 관한 에러가 표시됨)의 대상이 됩니다만, Postman은 그렇지 않습니다.이 질문은 "No Access-Control-Allow-Origin"을 수정하는 방법에 관한 것이 아닙니다." 오류입니다.왜 그런 일이 일어나느냐가 문제죠
투고를 중지하십시오.
- 모든 언어/프레임워크에 대응하는 CORS 설정.대신 해당 언어/프레임워크의 질문을 찾습니다.
- 서드파티 서비스로 CORS 회피 요청 가능
- 다양한 브라우저에서 CORS를 해제하기 위한 명령줄 옵션
RESTful API 내장 Flask에 접속하여 JavaScript를 이용한 인증을 시도하고 있습니다.그러나 요청 시 다음과 같은 오류가 발생합니다.
XMLHttpRequest는 http://myApiUrl/login을 로드할 수 없습니다.요청된 리소스에 'Access-Control-Allow-Origin' 헤더가 없습니다.따라서 오리진 'null'은 액세스가 허용되지 않습니다.
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를 실행하고 있습니다.따라서 브라우저는 보안상의 이유로 보통 같은 발신기지에서 요청을 허용하기 때문에 차단합니다.교차 도메인 요청을 수행하려면 다른 작업을 수행해야 합니다.그것을 실현하는 방법에 대한 튜토리얼은 「CORS 사용」입니다.
Postman을 사용하는 경우 이 정책에 의해 제한되지 않습니다.Cross-Origin XMLHttpRequest에서 인용:
일반 웹 페이지는 XMLHttpRequest 개체를 사용하여 원격 서버와 데이터를 주고받을 수 있지만 동일한 원본 정책에 의해 제한됩니다.확장은 그렇게 제한되지 않습니다.내선번호는 처음에 발신기지 간 권한을 요구하는 한 발신기지 외부에 있는 리모트서버와 통신할 수 있습니다.
경고: 사용 중
Access-Control-Allow-Origin: *
는 API/웹 사이트를 CSRF 공격에 취약하게 만들 수 있습니다.이 코드를 사용하기 전에 위험을 이해해야 합니다.
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-cors
$ pip install -U 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 설명서를 참조하십시오.
★★★★★★★★★★★★★★★★★★
$.ajax({type: "POST" - 콜옵션)
$.post() - POST 콜
둘 다 달라요.우체부가 'POST'를 올바르게 호출하지만 호출하면 'OPTIONS'가 됩니다.
C# 웹 서비스의 경우 - 웹 API
web.config 파일의 <시스템> 아래에 다음 코드를 추가해 주세요.webServer > 태그.이 조작은 유효합니다.
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
Ajax 콜에서 실수하지 않았는지 확인해 주세요.
j쿼리
$.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");
깊다
아래 API 조사에서는 당신의 질문에서 http://myApiUrl/login이 아닌 http://example.com을 사용합니다.이것은 첫 번째가 동작하기 때문입니다.당신의 페이지는 http://my-site.local:8088에 있을 겁니다.
메모: API와 페이지는 도메인이 다릅니다!
결과가 다른 이유는 우체국:
- header set " " "
Host=example.com
API) - header NOT set
Origin
- Postman은 실제로 당신의 웹사이트 URL을 전혀 사용하지 않습니다(Postman에 API 주소를 입력하기만 하면 됩니다).그는 API에만 요청을 보내기 때문에 그 웹사이트가 API와 동일한 주소를 가지고 있다고 가정합니다(브라우저는 이를 가정하지 않습니다).
가 동일한 있을 때 브라우저가도 헤더 합니다).Referer=http://my-site.local:8088
하지만 우체국에는 보이지 않습니다.)헤더가 설정되어 있지 않은 경우, 통상, 서버는 이러한 요구를 디폴트로 허가합니다.
이것이 Postman이 요청을 보내는 표준 방법입니다.그러나 사이트와 API의 도메인이 다를 경우 브라우저는 요청을 다르게 전송하고 CORS가 발생하며 브라우저는 자동으로 요청을 전송합니다.
- header sets 헤더
Host=example.com
) (API) - header sets 헤더
Origin=http://my-site.local:8088
의 사이트당신의 사이트)
(더))Referer
같은 값을 가지다와 같은 Origin
Chrome의 [콘솔과 네트워크(Console & Networks)]탭에 다음과 같이 표시됩니다.
이것이 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의 차단을 해제합니다(스타 대신 API를 소비하는 구체적인 페이지 주소를 사용합니다).
location ~ ^/index\.php(/|$) {
...
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
if ($request_method = OPTIONS) {
add_header 'Access-Control-Allow-Origin' "$http_origin"; # DO NOT remove THIS LINES (doubled with outside 'if' above)
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Max-Age' 1728000; # cache preflight value for 20 days
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'My-First-Header,My-Second-Header,Authorization,Content-Type,Accept,Origin';
add_header 'Content-Length' 0;
add_header 'Content-Type' 'text/plain charset=UTF-8';
return 204;
}
}
Apache(.htaccess 파일)에서 CORS를 유효하게 하는 설정 예를 다음에 나타냅니다.
# ------------------------------------------------------------------------------
# | Cross-domain Ajax requests |
# ------------------------------------------------------------------------------
# Enable cross-origin Ajax requests.
# http://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity
# http://enable-cors.org/
# <IfModule mod_headers.c>
# Header set Access-Control-Allow-Origin "*"
# </IfModule>
# Header set Header set Access-Control-Allow-Origin "*"
# Header always set Access-Control-Allow-Credentials "true"
Access-Control-Allow-Origin "http://your-page.com:80"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header always set Access-Control-Allow-Headers "My-First-Header,My-Second-Header,Authorization, content-type, csrf-token"
CORS 제한 적용은 서버에 의해 정의되고 브라우저에 의해 구현되는 보안 기능입니다.
브라우저는 서버의 CORS 정책을 확인하고 이를 준수합니다.
단, Postman 도구는 서버의 CORS 정책에 대해 신경 쓰지 않습니다.
그렇기 때문에 브라우저에는 CORS 에러가 표시되지만 포스트맨에는 표시되지 않습니다.
이 에러는, JavaScript가 ajax 요구를 실행하는 방법에 관한 몇개의 제한을 설정하는 CORS 규격에 의한 것입니다.
CORS 표준은 브라우저에 구현된 클라이언트 측 표준입니다.따라서 콜의 완료를 막고 오류 메시지를 생성하는 것은 서버가 아니라 브라우저입니다.
Postman은 CORS 제한을 실장하지 않기 때문에 Postman에서 같은 전화를 걸어도 같은 에러가 발생하지 않습니다.
Postman은 왜 CORS를 구현하지 않는가? CORS는 요청을 시작한 페이지의 원본(URL 도메인)에 관련된 제한을 정의합니다.그러나 Postman에서는 요청은 URL이 있는 페이지에서 발신되지 않으므로 CORS는 적용되지 않습니다.
솔루션 및 문제의 발생원
다른 도메인에 XMLHttpRequest를 작성하는 예:
- 1: 메 1 11:
some-domain.com
- 2: 메 2 2 2:
some-different-domain.com
도메인 이름의 이 차이는 Ajax, XMLHtpRequest 및 기타 HTTP 요청에서 동일한 도메인(즉, 오리진) 사용을 강제하는 SOP(Same-Origin Policy)라고 하는 CORS(Cross-Origin Resource Sharing) 정책을 트리거합니다.
Chrome Extension Postman으로 요청했는데 왜 작동했나요?
클라이언트(대부분의 브라우저 및 개발 도구)는 동일한 오리진 정책을 적용할 수 있습니다.
대부분의 브라우저는 CSRF(Cross-Site Request Formature) 공격과 관련된 문제를 방지하기 위해 동일한 오리진정책 정책을 적용합니다.
개발 도구로서의 Postman은 SOP를 적용하지 않기로 선택했지만 일부 브라우저는 SOP를 적용하기 때문에 JS를 통해 XMLHttpRequest로 전송할 수 없는 요청을 Postman을 통해 전송할 수 있습니다.
게이트웨이 시간 초과가 너무 짧고 액세스 중인 리소스가 시간 초과보다 처리하는 데 더 오래 걸리는 경우에도 이 오류가 발생할 수 있습니다.이는 복잡한 데이터베이스 쿼리 등이 해당될 수 있습니다.따라서 위의 에러 코드가 이 문제를 숨기고 있을 가능성이 있습니다.위의 Kamils 답변과 같이 에러 코드가 404가 아닌 504인지 확인하세요.504인 경우 게이트웨이 타임아웃을 늘리면 문제가 해결될 수 있습니다.
이 경우 IE 브라우저에서 동일한 원본 정책(CORS)을 비활성화하여 CORS 오류를 제거할 수 있습니다. 자세한 내용은 동일한 원본 정책 Internet Explorer를 비활성화하는 방법을 참조하십시오.이렇게 하면 로그에 완전히 504 오류가 기록되었습니다.
브라우저 테스트용:Windows - 실행:
chrome.exe --user-data-dir="C://Chrome dev session" --disable-web-security
하려면 , 이 을, 「의 행」에 기입해 주세요.doGet()
★★★★★★★★★★★★★★★★★」doPost()
하고 있는
response.setHeader("Access-Control-Allow-Origin", "*");
"*"
웹 사이트 또는 웹 사이트에 액세스하는 api URL 끝점을 입력합니다.
IP가 화이트리스트에 없기 때문에 이 에러가 발생합니다.백엔드 직원에게 https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers에 접속하는 서비스의 IP를 화이트리스트로 지정하도록 의뢰합니다.
「최신 수리는, Moesif CORS 확장을 인스톨 하는 것입니다.https://chrome.google.com/webstore/detail/moesif-origin-cors-change/digfbfaphojjndkpccljibejjbppifbc/related?hl=en-US
인스톨이 완료되면, 브라우저로 클릭해 확장을 유효하게 합니다.아이콘의 라벨이 "off"에서 "On"으로 변경되었는지 확인합니다.
그런 다음 응용 프로그램을 새로 고치면 API 요청이 작동합니다."
이 미들웨어를 글로벌하게 적용함으로써 기능합니다.
<?php
namespace App\Http\Middleware;
use Closure;
class Cors {
public function handle($request, Closure $next) {
return $next($request)
->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
->header('Access-Control-Allow-Headers', "Accept,authorization,Authorization, Content-Type");
}
}
언급URL : https://stackoverflow.com/questions/20035101/why-does-my-javascript-code-receive-a-no-access-control-allow-origin-header-i
'programing' 카테고리의 다른 글
JavaScript는 객체 속성 순서를 보증합니까? (0) | 2022.12.09 |
---|---|
컴파일 오류가 발생하지 않고 vue에서 조건부 템플릿별로 열기 및 닫기 태그를 구분하는 방법은 무엇입니까? (0) | 2022.12.09 |
PHP dirname(_FILE__)에서 한 단계 위로 올라가는 방법 (0) | 2022.12.09 |
코틀린의 개인 건설업자 (0) | 2022.12.09 |
Linux에서 Java Application as a Service 실행 (0) | 2022.12.09 |