etc./StackOverFlow

내 JavaScript 코드는 "요청된 리소스에 'Access-Control-Allow-Origin' 헤더가 없습니다" 오류를 수신하지만 Postman은 그렇지 않은 이유는 무엇입니까?

청렴결백한 만능 재주꾼 2021. 11. 10. 07:35
반응형

질문자 :Mr Jedi


Mod note : 이 질문은 왜 XMLHttpRequest / fetch /etc에 관한 것입니다. 브라우저의 경우 동일한 액세스 정책 제한이 적용되지만(CORB 또는 CORS를 언급하는 오류가 발생함) Postman은 그렇지 않습니다. 이 질문은 "No 'Access-Control-Allow-Origin'..." 오류를 수정하는 방법에 관한 것이 아닙니다. 그것이 일어나는 이유에 관한 것입니다.

게시를 중지하십시오 :


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

XMLHttpRequest는 http://myApiUrl/login을 로드할 수 없습니다. 요청한 리소스에 'Access-Control-Allow-Origin' 헤더가 없습니다. 따라서 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를 수행하고 있는 것입니다. 따라서 브라우저는 일반적으로 보안상의 이유로 동일한 출처에서 요청을 허용하므로 이를 차단합니다. 도메인 간 요청을 수행하려면 다른 작업을 수행해야 합니다. 이를 달성하는 방법에 대한 튜토리얼은 Using CORS 입니다.

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

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


MD. Sahib Bin Mahboob

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

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

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

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

 // 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 cor를 포함합니다.

 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 문서를 확인하세요.


Shady Mohamed Sherif

때문에
$.ajax({type: "POST" - 옵션 호출
$.post( - POST 호출

둘 다 다릅니다. Postman은 "POST"를 올바르게 호출하지만 우리가 호출하면 "OPTIONS"가 됩니다.

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

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

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

Ajax 호출에 실수가 없는지 확인하십시오.

제이쿼리

 $.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");

George Livingston

API로 아래 조사에서 http://myApiUrl/login 대신 http://example.com을 사용합니다. 이 첫 번째 항목이 작동하기 때문입니다.

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

다른 결과가 표시되는 이유는 Postman이 다음을 수행하기 때문입니다.

  • 헤더 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를 켜는 구성의 예 입니다. nginx의 경우 always/"$http_origin" 을, "*" 를 설정할 때 매우 주의하십시오. 그러면 모든 도메인에서 CORS 차단이 해제됩니다.

 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"


Kamil Kiełczewski

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

브라우저는 서버의 CORS 정책을 보고 이를 준수합니다.

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

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


Gopinath

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

사용 사례: Chrome에서 Spring REST 끝점을 각도로 호출하려고 할 때.

여기에 이미지 설명 입력

솔루션: 각 컨트롤러 클래스 위에 @CrossOrigin("*") 주석을 추가합니다.

여기에 이미지 설명 입력


Kms

자바 스크립트에서 fetch API 또는 XMLHttpRequest로 내용을 가져올 때 해당 제한을 우회하려면 프록시 서버를 사용하여 헤더 Access-Control-Allow-Origin * 설정할 수 있습니다.

 const express = require('express'); const request = require('request'); const app = express(); app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); next(); }); app.get('/fetch', (req, res) => { request( { url: req.query.url }, (error, response, body) => { if (error || response.statusCode !== 200) { return res.status(500).send('error'); } res.send(body); } ) }); const PORT = process.env.PORT || 3000; app.listen(PORT, () => console.log(`listening on ${PORT}`));

위는 프록시 서버로 작동할 수 있는 샘플 코드( node Js required )입니다. 예: https://www.google.com 일반적으로 가져오려는 경우 CORS 오류가 발생하지만 이제 요청이 포트 3000에서 로컬로 호스팅되는 프록시 서버를 통해 전송되기 때문에 프록시 서버는 Access-Control-Allow-Origin 헤더가 있으면 문제가 발생하지 않습니다.

가져오려는 URL로 요청을 직접 보내는 대신 http://localhost:3000/fetch?url= Your URL here

Your URL here 에 있는 URL은 가져오려는 URL을 나타냅니다(예: https://www.google.com


Adwaith

발생하는 오류는 JavaScript가 ajax 요청을 수행하는 방법에 대한 몇 가지 제한을 설정하는 CORS 표준으로 인한 것입니다.

CORS 표준은 브라우저에서 구현되는 클라이언트 측 표준입니다. 따라서 호출이 완료되는 것을 방지하고 오류 메시지를 생성하는 것은 서버가 아니라 브라우저입니다.

Postman은 CORS 제한을 구현하지 않으므로 Postman에서 동일한 호출을 할 때 동일한 오류가 표시되지 않습니다.

Postman이 CORS를 구현하지 않는 이유는 무엇입니까? CORS는 요청을 시작하는 페이지의 원본(URL 도메인)과 관련된 제한 사항을 정의합니다. 그러나 Postman에서 요청은 URL이 있는 페이지에서 시작되지 않으므로 CORS가 적용되지 않습니다.


JacquesB

.NET Core Web API 프로젝트에 대해서만 다음 변경 사항을 추가합니다.

  1. Startup.cs 파일의 ConfigureServices() services.AddMvc() 줄 뒤에 다음 코드를 추가합니다.
 services.AddCors(allowsites=>{allowsites.AddPolicy("AllowOrigin", options => options.AllowAnyOrigin()); });
  1. Startup.cs 파일의 Configure() app.UseMvc() 줄 뒤에 다음 코드를 추가합니다.
 app.UseCors(options => options.AllowAnyOrigin());
  1. 도메인 외부에서 액세스하려는 컨트롤러를 열고 컨트롤러 수준에서 다음 속성을 추가합니다.
 [EnableCors("AllowOrigin")]

Shakti Srivastav

내 답변을 다시 게시하면 중재자가 삭제되었습니다. 내가 언급했듯이 OP의 정확한 오류는 이것으로 수정되었습니다. 이 답변이 삭제되기 전에 최소 7명의 다른 사람들이 유효한 솔루션이라는 데 동의했습니다.

중재자: 외부 문제로 인해 한 사람이 문제를 해결하도록 돕는 것의 가치를 고려하십시오. 자바스크립트 메시지는 이 특정 문제를 디버깅하는 데 여전히 거의 쓸모가 없습니다. 이 스레드는 여전히 OP의 정확한 오류 메시지에 대한 상위 검색 결과입니다.

삭제된 답변은 다음과 같습니다.

인기 있는 질문 -- 여기까지 읽었지만 도움이 되지 않았다면 살펴봐야 할 또 다른 질문입니다. Akamai, Limelight 또는 이와 유사한 CDN이 있는 경우 리소스의 URI에 대해 보유한 캐시 키를 확인하는 것이 좋습니다. Origin 헤더 값이 포함되어 있지 않으면 다른 Origin에서 요청할 때 캐시된 응답을 반환할 수 있습니다. 우리는 이것을 디버깅하는 데 반나절을 보냈습니다. CDN 구성은 우리 소유의 일부 선택 도메인에 대한 Origin 값만 포함하고 다른 모든 도메인에 대해서는 이 값을 null로 설정하도록 업데이트되었습니다. 이것은 작동하는 것으로 보이며 알려진 도메인의 브라우저에서 리소스를 볼 수 있습니다. 확실히 다른 모든 답변은 여기에 도달하기 위한 전제 조건이지만 CDN이 브라우저의 첫 번째 홉인 경우 검토해야 할 사항입니다.

우리의 경우 우리는 우리 서비스에 대한 일부 요청을 볼 수 있었지만 사이트에서 보내는 양은 거의 없었습니다. 그것은 우리에게 CDN을 지적했습니다. 돌아가서 원래 요청이 브라우저 AJAX 호출의 일부가 아닌 직접 요청에서 제공되었으며 응답 헤더 Access-Control-Allow-Origin이 포함되지 않았음을 확인할 수 있습니다. 분명히 CDN은 이 값을 캐시했습니다. 일치의 일부로 Origin 요청 헤더 값을 고려하도록 Akamai CDN 구성을 조정한 덕분에 제대로 작동한 것 같습니다.


No Refunds No Returns

.NET을 중간 계층으로 사용하는 경우 route 속성을 명확하게 확인하십시오. 예를 들어,

이랬을 때 문제가 있었는데,

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

이것으로 고쳐서,

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

Sai Vaibhav Medavarapu

Google, Typekit 등의 웹폰트를 사용하고 있습니까? @font-face 또는 CSS3 방법과 같은 웹 글꼴을 사용할 수 있는 방법은 여러 가지가 있습니다. Firefox 및 IE와 같은 일부 브라우저는 동일한 보안상의 이유로 블로그와 같은 비표준 타사 URL에서 글꼴을 포함하는 경우 글꼴 포함을 거부할 수 있습니다.

WordPress 블로그 문제를 해결하려면 아래를 .htaccess 파일에 넣으세요.

 <IfModule mod_headers.c> <FilesMatch "\.(ttf|ttc|otf|eot|woff|woff2|font.css|css|js)$"> Header set Access-Control-Allow-Origin "*" </FilesMatch> </IfModule>

출처 : https://crunchify.com/how-to-fix-access-control-allow-origin-issue-for-your-https-enabled-wordpress-site-and-maxcdn/


Mizhar Raja

출처 : http:www.stackoverflow.com/questions/20035101/why-does-my-javascript-code-receive-a-no-access-control-allow-origin-header-i

반응형