Żądany zasób nie zawiera nagłówka „Access-Control-Allow-Origin”. Dlatego też pochodzenie „…” nie jest dozwolone


135

Używam .htaccess do przepisywania adresów URL i użyłem podstawowego tagu html, aby to działało.

Teraz, kiedy próbuję wysłać żądanie AJAX, pojawia się następujący błąd:

Nie można załadować XMLHttpRequest http://www.example.com/login.php. Żądany zasób nie zawiera nagłówka „Access-Control-Allow-Origin”. http://example.comDlatego Origin „ ” nie ma dostępu.


1
Nieważne ... teraz działa, nawet nie wiem, jaki był błąd: S
— Th3lmuu90

8
Choć subtelna, http://wordicious.comto inna dziedzina niż http://www.wordicious.com/, stąd błąd. Przy okazji, jeśli teraz działa i wrócił sam, prawdopodobnie powinieneś usunąć pytanie.
— acdcjunior

@acdcjunior Wygląda na to, że jest to błąd, który jest z Twojej wnikliwej obserwacji. Jeśli opublikujesz to jako odpowiedź, zagłosowałbym za tym.
— Waleed Khan

5
Dobrze, że pytanie nie zostało usunięte, bo inaczej bym go dziś nie widział!
— icedwater

Odpowiedzi:


170

Użyj addHeaderZamiast używać setHeadermetody,

response.addHeader("Access-Control-Allow-Origin", "*");

*w powyższej linii pozwoli access to all domains.


Za pozwolenie access to specific domain only:

response.addHeader("Access-Control-Allow-Origin", "http://www.example.com");

Sprawdź to blog post.


4
pokazuje, że addheader nie jest zdefiniowany. Czy możesz to wyjaśnić?
— Vaisakh Pc

9
Gdzie mam umieścić te linie?
— DaveWalley

14
Gdzie należy to dodać?
— Alex

1
Ten post na blogu mówi o Node.js i express. Nie javascript po stronie klienta. czy ktoś może potwierdzić, czy to działa?
— Sam Eaton

1
Nie sądzę, aby ta konfiguracja mogła być wykonana tylko po stronie klienta. Więc gdzie to umieścić, to będzie kod po stronie serwera (prawdopodobnie podczas budowania odpowiedzi na żądanie)
— Chirag Ravindra

145

Dlaczego pojawia się błąd:

Kod JavaScript jest ograniczony przez zasady tego samego pochodzenia , co oznacza, że ​​ze strony pod adresem www.example.commożna wysyłać żądania (AJAX) tylko do usług znajdujących się w dokładnie tej samej domenie, w takim przypadku dokładnie www.example.com( nie example.com - bez www- lub whatever.example.com).

W Twoim przypadku kod Ajax próbuje dotrzeć do usługi http://wordicious.comze strony znajdującej się pod adresem http://www.wordicious.com.

Chociaż bardzo podobne, są one nie tej samej domenie. A jeśli nie znajdują się w tej samej domenie, żądanie zakończy się powodzeniem tylko wtedy, gdy odpowiedź celu zawiera rozszerzenieAccess-Control-Allow-Origin nagłówek.

Jako Twoja strona / usługa pod adresem http://wordicious.com nigdy nie została skonfigurowana do przedstawiania takiego nagłówka, wyświetlany jest ten komunikat o błędzie.

Rozwiązanie:

Jak już powiedziano, domena źródłowa (gdzie znajduje się strona z JavaScriptem) i docelowa (gdzie JavaScript próbuje dotrzeć) domeny muszą być dokładne taka sama.

Twoja sprawa wygląda na literówkę. Wygląda na to http://wordicious.comi http://www.wordicious.comfaktycznie są tym samym serwerem / domeną. Aby to naprawić, wpisz cel i źródło jednakowo: spraw, aby kod Ajax żądał stron / usług, aby http://www.wordicious.comniehttp://wordicious.com . (Może względnie umieść docelowy adres URL, na przykład '/login.php'bez domeny).



Bardziej ogólna uwaga:

Jeśli problem nie jest literówką, jak wydaje się to pytanie, rozwiązaniem byłoby dodanie Access-Control-Allow-Origindomeny docelowej . Dodanie zależy oczywiście od serwera / języka za tym adresem. Czasami wystarczy zmienna konfiguracyjna w narzędziu. Innym razem będziesz musiał samodzielnie dodać nagłówki za pomocą kodu.


62

W przypadku serwera .NET można to skonfigurować w pliku web.config, jak pokazano poniżej

 <system.webServer>
   <httpProtocol>
     <customHeaders>
       <add name="Access-Control-Allow-Origin" value="your_clientside_websiteurl" />
     </customHeaders>
   </httpProtocol>
 </system.webServer>

Na przykład powiedzmy, że jeśli domena serwera to http://live.makemypublication.com, a klient to http://www.makemypublication.com, to skonfiguruj w pliku web.config serwera, jak poniżej

 <system.webServer>
   <httpProtocol>
     <customHeaders>
       <add name="Access-Control-Allow-Origin" value="http://www.makemypublication.com" />
     </customHeaders>
  </httpProtocol>
 </system.webServer>

Jeszcze lepsze rozwiązanie. Dzięki
— ANJYR - KODEXPRESSION

Wielkie dzięki. Uratowałeś mi cały dzień.
— Prateek Gupta

Działa nawet po 2 latach: p
— Wszechobecni deweloperzy

1
@SyedAliTaqi pytanie brzmi php, dlatego odpowiedź jest niedoceniana. jednak to zadziałało również dla mnie :)
— Ahmad Th

22

Jeśli otrzymasz ten komunikat o błędzie z przeglądarki:

Żądany zasób nie zawiera nagłówka „Access-Control-Allow-Origin”. Dlatego też pochodzenie „…” nie jest dozwolone

kiedy próbujesz wysłać żądanie Ajax POST / GET do zdalnego serwera, na który nie masz wpływu, zapomnij o tej prostej poprawce:

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

To, co naprawdę musisz zrobić, zwłaszcza jeśli używasz JavaScript tylko do wykonania żądania Ajax, to wewnętrzny serwer proxy, który przyjmuje zapytanie i wysyła je do zdalnego serwera.

Najpierw w JavaScript wykonaj wywołanie Ajax do własnego serwera, na przykład:

$.ajax({
    url: yourserver.com/controller/proxy.php,
    async:false,
    type: "POST",
    dataType: "json",
    data: data,
    success: function (result) {
        JSON.parse(result);
    },
    error: function (xhr, ajaxOptions, thrownError) {
        console.log(xhr);
    }
});

Następnie utwórz prosty plik PHP o nazwie proxy.php, aby opakować dane POST i dołączyć je do zdalnego serwera URL jako parametry. Podaję przykład, jak omijam ten problem za pomocą interfejsu API wyszukiwania hoteli Expedia:

if (isset($_POST)) {
  $apiKey = $_POST['apiKey'];
  $cid = $_POST['cid'];
  $minorRev = 99;

  $url = 'http://api.ean.com/ean-services/rs/hotel/v3/list?' . 'cid='. $cid . '&' . 'minorRev=' . $minorRev . '&' . 'apiKey=' . $apiKey;

  echo json_encode(file_get_contents($url));
 }

Wykonując:

 echo json_encode(file_get_contents($url));

Po prostu wykonujesz to samo zapytanie, ale po stronie serwera i po tym powinno działać dobrze.


@NizarBsb jesteś szalony, wiesz o tym !!!!! : D, wielkie dzięki, twoja odpowiedź uratowała mi życie
— Flash

10

Musisz to dodać na początku swojej strony php "login.php"

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

5
Zdecydowanie nie jest bezpieczne.
— oddzwonienie

7

musisz umieścić klucze / wartości nagłówków w odpowiedzi metody options. na przykład, jeśli masz zasób pod adresem http://mydomain.com/myresource , to w kodzie serwera piszesz

//response handler
void handleRequest(Request request, Response response) {
    if(request.method == "OPTIONS") {
       response.setHeader("Access-Control-Allow-Origin","http://clientDomain.com")
       response.setHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
       response.setHeader("Access-Control-Allow-Headers", "Content-Type");
    }



}

3

Zasadniczo zmień odpowiedź nagłówka API, dodając następujące dodatkowe parametry.

Access-Control-Allow-Credentials: prawda

Access-Control-Allow-Origin: *

Ale to nie jest dobre rozwiązanie, jeśli chodzi o bezpieczeństwo


3

Aby obejść ten problem, należy użyć zwrotnego proxy działającego na hoście „źródłowym” i przekazującego do serwera docelowego, takiego jak Fiddler:

Link tutaj: http://docs.telerik.com/fiddler/configure-fiddler/tasks/usefiddlerasreverseproxy

Lub Reverse proxy Apache ...


można to zrobić na poziomie konfiguracji Apache lub Nginx dla domeny. np. jeśli użytkownik uzyskuje dostęp do mysite.com (bez www), a XHR żąda adresu www.mysite.com, czy dyrektywa htaccess lub httpd.conf może rozwiązać ten problem?
— codecowboy

Jasne, Twoja aplikacja frontendowa powinna zachowywać się jak odwrotny serwer proxy. np. w przypadku Apache musisz zainstalować mod_proxy i skonfigurować swoje reguły za pomocą ProxyPassReverse ( httpd.apache.org/docs/current/mod/ ... ). Wydaje się, że te same funkcje są dostępne również na Nginx: wiki.nginx.org/LikeApache
— hzrari

2

Dodaj to do pliku PHP lub głównego kontrolera

header("Access-Control-Allow-Origin: http://localhost:9000");

aby zakończyć - potrzebujesz równieżheader("Access-Control-Allow-Credentials: true");
— Adam

1

Rozwiązano poniższy wpis w httpd.conf

#CORS Issue
Header set X-Content-Type-Options "nosniff"
Header always set Access-Control-Max-Age 1728000
Header always set Access-Control-Allow-Origin: "*"
Header always set Access-Control-Allow-Methods: "GET,POST,OPTIONS,DELETE,PUT,PATCH"
Header always set Access-Control-Allow-Headers: "DNT,X-CustomHeader,Keep-Alive,Content-Type,Origin,Authentication,Authorization,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control"
Header always set Access-Control-Allow-Credentials true

#CORS REWRITE
RewriteEngine On                  
RewriteCond %{REQUEST_METHOD} OPTIONS 
#RewriteRule ^(.*)$ $1 [R=200,L]
RewriteRule ^(.*)$ $1 [R=200,L,E=HTTP_ORIGIN:%{HTTP:ORIGIN}]]

Jedyny sposób, który działał dla mnie na Apache2, CentOS7, Larravel 5 i React
— Shakiba Moshiri

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.