Dlaczego mój kod JavaScript otrzymuje błąd "Brak nagłówka 'Access-Control-Allow-Origin' na żądanym zasobie", podczas gdy listonosz nie?
MOD note: to pytanie dotyczy tego, dlaczego listonosz nie podlega ograniczeniom CORS w taki sam sposób jak XMLHttpRequest. To pytanie jest NIE o tym, jak naprawić "brak' kontroli dostępu-Zezwalaj na pochodzenie'..."błąd.
Proszę przestać pisać :
- konfiguracja Kors dla każdego języka / frameworka pod słońcem. Zamiast znajdź odpowiednie pytanie dotyczące języka / frameworka.
- usługi stron trzecich, które pozwala na ominięcie Kors
- opcje wiersza poleceń do wyłączania Kors dla różnych przeglądarek
Próbuję wykonać autoryzację używając JavaScript {[15] } łącząc się z RESTful API wbudowane Flask. Jednak, kiedy składam wniosek, dostaję następujący błąd:
XMLHttpRequest nie może załadować http://myApiUrl/login . Nie ma nagłówka' Access-Control-Allow-Origin ' na żądany zasób. Origin 'null' nie ma zatem dostępu.
Wiem, że API lub zdalny zasób musi ustawić nagłówek, ale dlaczego to działało, gdy złożyłem żądanie przez rozszerzenie Chrome Postman?
To jest kod zapytania:
$.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);
});
11 answers
Jeśli dobrze zrozumiałem robisz XMLHttpRequest do innej domeny niż Twoja strona jest na. Tak więc przeglądarka blokuje ją, ponieważ zwykle zezwala na żądanie w tym samym miejscu pochodzenia ze względów bezpieczeństwa. Musisz zrobić coś innego, jeśli chcesz wykonać żądanie między domenami. Tutorial o tym jak to osiągnąć jest Korzystanie z CORS.
Kiedy korzystasz z listonosza, nie są one ograniczone przez tę politykę. Cytowany z Cross-Origin XMLHttpRequest:
Zwykłe strony internetowe mogą używać obiektu XMLHttpRequest do wysyłania i odbierania danych ze zdalnych serwerów, ale są one ograniczone tą samą Polityką origin. Rozszerzenia nie są tak ograniczone. Rozszerzenie może rozmawiać ze zdalnymi serwerami spoza swojego źródła, o ile najpierw zażąda uprawnień cross-origin.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-23 00:46:57
WARNING: Korzystanie z
Access-Control-Allow-Origin: *
może sprawić, że Twój API/strona internetowa będzie podatna na ataki cross-site request forgery (CSRF). Upewnij się, że rozumiesz ryzyko przed użyciem tego kodu.
Jest to bardzo proste do rozwiązania, jeśli używasz PHP. Wystarczy dodać następujący skrypt na początku strony PHP, który obsługuje żądanie:
<?php header('Access-Control-Allow-Origin: *'); ?>
Jeśli używasz node-red musisz zezwolić CORS w pliku node-red/settings.js
nie komentując następujących linijek:
// 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"
},
Jeśli używasz Flask to samo co pytanie; musisz najpierw zainstalować flask-cors
$ pip install -U flask-cors
Następnie dołącz Cors kolby do aplikacji.
from flask_cors import CORS
Prosta aplikacja będzie wyglądać następująco:
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
@app.route("/")
def helloWorld():
return "Hello, cross-origin-world!"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-27 03:06:55
Ponieważ
$.ajax({type: "POST" - calls OPTIONS
$.post ( - wywołania POST
Dla C# web services- Web API
Proszę dodać poniższy kod w swojej stronie.plik config W tag. To zadziała:
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
Upewnij się, że nie robisz żadnego błędu w Ajaxie call
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");
}
});
Uwaga: Jeśli szukasz pobierania zawartości z zewnętrznej strony internetowej, to to Ci nie pomoże. Możesz wypróbować następujący kod, ale nie JavaScript.
System.Net.WebClient wc = new System.Net.WebClient();
string str = wc.DownloadString("http://mysite.microsoft.sample.xyz.com/api/mycall");
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55
W poniższym dochodzeniu jako API używam http://example.com zamiast http://myApiUrl/login z twojego pytania, bo to pierwsze działa.
Zakładam, że Twoja strona jest na http://my-site.lokalne:8088.
Powodem, dla którego widzisz różne wyniki, Jest to, że listonosz:
- set header
Host=example.com
(twoje API) - nie ustawia nagłówka
Origin
Jest to podobne do sposobu wysyłania żądań przez przeglądarki gdy strona i API mają tę samą domenę (przeglądarki ustawiają również element nagłówka Referer=http://my-site.local:8088
, jednak nie widzę go w Postmanie). gdy Origin
nagłówek jest ustawiony , a nie, zazwyczaj serwery domyślnie zezwalają na takie żądania.
Jest to standardowy sposób, w jaki Listonosz wysyła żądania. Ale przeglądarka wysyła żądania inaczej, gdy Twoja strona i API mają różne domeny , a następnie CORS i przeglądarka automatycznie:
- ustawia nagłówek
Host=example.com
(twój jako API) - ustawia nagłówek
Origin=http://my-site.local:8088
(Twoja strona)
(nagłówek Referer
ma taką samą wartość jak Origin
). A teraz w zakładce Chrome ' A Console & Networks zobaczysz:
Kiedy masz Host != Origin
jest to CORS, a gdy serwer wykryje takie żądanie, zazwyczaj blokuje je domyślnie.
Origin=null
jest ustawiony, gdy Otwórz zawartość HTML z lokalnego katalogu i wyśle żądanie. Podobnie jest w przypadku wysłania żądania wewnątrz <iframe>
, jak w poniższym fragmencie (ale tutaj nagłówek Host
nie jest w ogóle ustawiony) - ogólnie, wszędzie tam, gdzie Specyfikacja HTML mówi o nieprzezroczystym pochodzeniu, można to przetłumaczyć na Origin=null
. Więcej informacji na ten temat można znaleźć tutaj .
fetch('http://example.com/api', {method: 'POST'});
Look on chrome-console > network tab
Jeśli nie korzystasz z prostego żądania CORS, zazwyczaj przeglądarka automatycznie również wysyła żądanie opcji przed wysłaniem głównego żądania-więcej informacji znajduje się tutaj . Poniższy fragment pokazuje to:
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)
Możesz zmienić konfigurację serwera, aby zezwolić na żądania CORS.
Jest to bardzo proste i łatwe w obsłudze narzędzie, które pozwala na szybkie i łatwe uruchamianie aplikacji.plik conf) - bądź bardzo ostrożny z ustawieniemalways/"$http_origin"
dla nginx i "*"
dla Apache - odblokuje to CORS z dowolnego domena.
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;
}
}
Oto przykładowa konfiguracja, która włączaCORS na Apache (.plik htaccess)
# ------------------------------------------------------------------------------
# | 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"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-26 19:09:53
Stosowanie ograniczenia CORS jest funkcją bezpieczeństwa zdefiniowaną przez serwer i zaimplementowaną przez przeglądarkę .
Przeglądarka patrzy na politykę Kors serwera i szanuje ją.
Jednak Narzędzie Postman nie przejmuje się polityką CORS serwera.
Dlatego błąd CORS pojawia się w przeglądarce, ale nie w Postmanie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-08 18:09:04
Napotkał ten sam błąd w różnych przypadkach użycia.
Przypadek użycia: w chrome, gdy próbowano wywołać Spring REST punkt końcowy w kącie.
Rozwiązanie: Add @ CrossOrigin("*") adnotacja na górze odpowiedniej klasy kontrolera.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-05-25 05:45:54
Jeśli chcesz ominąć to ograniczenie podczas pobierania zawartości za pomocą API fetch lub XMLHttpRequest w javascript, możesz użyć serwera proxy, aby ustawić nagłówek Access-Control-Allow-Origin
na *
.
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}`));
Powyżej znajduje się przykładowy kod (wymagany węzeł Js), który może działać jako serwer proxy. Na przykład: jeśli chcę pobrać https://www.google.com
normalnie błąd CORS jest wyrzucany, ale teraz, ponieważ żądanie jest wysyłane przez serwer proxy hostowany lokalnie na porcie 3000, serwer proxy dodaje nagłówek Access-Control-Allow-Origin
w odpowiedzi i nie będzie żadnego problemu.
Wyślij zapytanie GET do http://localhost:3000/fetch?url = Your URL here
, zamiast bezpośrednio wysyłać żądanie na adres URL, który chcesz pobrać.
Your URL here
oznacza adres URL, który chcesz pobrać np: https://www.google.com
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-07-21 17:06:46
Tylko dla projektu. NET Core Web API, dodaj następujące zmiany:
- Dodaj następujący kod po linii
services.AddMvc()
w metodzieConfigureServices()
uruchamiania.plik cs:
services.AddCors(allowsites=>{allowsites.AddPolicy("AllowOrigin", options => options.AllowAnyOrigin());
});
- Dodaj następujący kod po linii
app.UseMvc()
w metodzieConfigure()
uruchamiania.plik cs:
app.UseCors(options => options.AllowAnyOrigin());
- Otwórz kontroler, do którego chcesz uzyskać dostęp poza domeną i dodaj następujący atrybut na poziomie kontrolera:
[EnableCors("AllowOrigin")]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-18 17:24:00
Otrzymany błąd wynika ze standardu CORS, który określa pewne ograniczenia dotyczące sposobu wykonywania żądań ajax przez JavaScript.
Standard CORS jest Standardem po stronie klienta, zaimplementowanym w przeglądarce. Tak więc to przeglądarka uniemożliwia zakończenie połączenia i generuje komunikat o błędzie - Nie serwer.
Listonosz nie implementuje ograniczeń Kors, dlatego nie widzisz tego samego błędu podczas wykonywania tego samego połączenia od listonosza.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-09 21:37:06
Jeśli używasz. NET jako warstwy środkowej, sprawdź wyraźnie atrybut trasy, na przykład
Miałem problem, kiedy to było tak,
[Route("something/{somethingLong: long}")] //Space.
Naprawiłem to przez to,
[Route("something/{somethingLong:long}")] //No space
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-09 17:08:51
Czy używasz Webfontów z Google, Typekit, itp? Istnieje wiele sposobów, w jakie można użyć metod Webfontów, takich jak @font-face lub CSS3, niektóre przeglądarki, takie jak Firefox i IE, mogą odmówić osadzenia czcionki, gdy pochodzi ona z niestandardowego adresu URL strony trzeciej (np.
Aby rozwiązać problem na swoim blogu WordPress, po prostu umieść poniżej w swoim .plik htaccess.
<IfModule mod_headers.c>
<FilesMatch "\.(ttf|ttc|otf|eot|woff|woff2|font.css|css|js)$">
Header set Access-Control-Allow-Origin "*"
</FilesMatch>
</IfModule>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-12-06 01:02:37