Żą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.

Th3lmuu90
źródło
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.

Jay Patel
źródło
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.

acdcjunior
źródło
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>
Naga
źródło
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.

Nizar B.
źródło
@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: *'); ?>
Shady Sherif
źródło
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");
    }



}
i-systech.com
źródło
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

Piusha
źródło
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 ...

hzrari
źródło
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");
Sam
źródło
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}]]
Sandeep540
źródło
Jedyny sposób, który działał dla mnie na Apache2, CentOS7, Larravel 5 i React
Shakiba Moshiri