2012-06-04 9 views
70

Utknąłem z tym problemem CORS, mimo że ustawiłem serwer (nginx/node.js) z odpowiednimi nagłówkami.Śmiertelny CORS, gdy http: // localhost jest pochodzenia

widzę w okienku Chrome Network -> Nagłówki odpowiedzi:

Access-Control-Allow-Origin:http://localhost 

który powinien załatwić sprawę.

Oto kod, który teraz używać do badania:

var xhr = new XMLHttpRequest(); 
xhr.onload = function() { 
    console.log('xhr loaded'); 
}; 
xhr.open('GET', 'http://stackoverflow.com/'); 
xhr.send(); 

dostaję

XMLHttpRequest cannot load http://stackoverflow.com/. Origin http://localhost is not allowed by Access-Control-Allow-Origin. 

Podejrzewam, że jest to problem w skrypcie klienckim a nie konfiguracji serwera ...

+17

Nie, stackoverflow.com musi ustawić ten nagłówek, nie ty. : x. Jaki byłby cel polityki tego samego pochodzenia w przeciwnym razie. – Esailija

+2

Spróbuj uzyskać dostęp do skonfigurowanego serwera bez przepełnienia stosu. ;) – Nek

+0

DOH! Czy istnieje sposób, aby powiedzieć chrome (lub innej przeglądarce), aby uzyskać zasób, nawet jeśli brakuje nagłówka, gdy moje pochodzenie jest localhost? – whadar

Odpowiedz

117

Chrome does not support localhost for CORS requests (otwarty błąd od 2010).

Aby obejść ten problem, można użyć domeny takiej jak lvh.me (która wskazuje 127.0.0.1, podobnie jak localhost) lub rozpocząć chromowanie z flagą --disable-web-security (zakładając, że właśnie testujesz).

+0

To nie jest poprawne. Jestem w stanie opublikować post na localhost z chrome – greensuisse

+10

@greensuisse - nie publikuje się na localhost. To jest wysyłanie * z * localhost, który jest problemem. – Cheeso

+1

Ten błąd jest nieprawidłowy (i został oznaczony jako taki - http://crbug.com/67743#c17). [Komentarz Esailiji] (http://stackoverflow.com/questions/10883211/deadly-cors-when-http-localhost-is-the-origin#comment14184025_10883211) jest poprawny, dodanie tych nagłówków do localhost nie da ci magicznie dostępu do wszystkie inne witryny. Jest to witryna zdalna, która musi być obsługiwana z tymi nagłówkami. –

15

Prawdziwym problemem jest to, że jeśli ustawimy -Allow- dla wszystkich żądań (OPCJE & POST), Chrome je anuluje. Poniższy kod działa dla mnie z POST na localhost z Chrome

<?php 
if (isset($_SERVER['HTTP_ORIGIN'])) { 
    //header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}"); 
    header("Access-Control-Allow-Origin: *"); 
    header('Access-Control-Allow-Credentials: true');  
    header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); 
} 
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { 
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])) 
     header("Access-Control-Allow-Methods: GET, POST, OPTIONS");   
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) 
     header("Access-Control-Allow-Headers:{$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}"); 

    exit(0); 
} 
?> 
+2

OP używa pliku nginx/node.js. Nie PHP –

4

Per @ odpowiedź Beau, Chrome nie obsługuje localhost Cors żądań, i jest mało prawdopodobne, wszelkie zmiany w tym kierunku.

Używam Allow-Control-Allow-Origin: * Chrome Extension do obejścia tego problemu. Rozszerzenie będzie dodać niezbędne nagłówki HTTP dla CORS:

Access-Control-Allow-Origin: * 
Access-Control-Allow-Methods: "GET, PUT, POST, DELETE, HEAD, OPTIONS" 
Access-Control-Expose-Headers: <you can add values here> 

source code is published on Github.

Pamiętaj, że rozszerzenie automatycznie filtruje wszystkie adresy URL. Może to spowodować uszkodzenie niektórych stron internetowych (na przykład: Dropbox). Zmieniłem go filtrować tylko localhost URL z poniższego filtra URL

*://localhost:*/*