Pochodzenie nie jest dozwolone przez Access-Control-Allow-Origin


337

Robię Ajax.requestna zdalnym serwerze PHP w aplikacji Sencha Touch 2 ( zawartej w PhoneGap ).

Odpowiedź serwera jest następująca:

XMLHttpRequest nie może załadować http://nqatalog.negroesquisso.pt/login.php . Pochodzenie http://localhost:8888nie jest dozwolone przez Access-Control-Allow-Origin.

Jak mogę rozwiązać ten problem?


19
podczas korzystania z jQuery, ustawienie dataType: 'jsonp',robi
— załatwienie

11
tak przy okazji, to nie jest odpowiedź serwera. Mówiąc ściślej, ten błąd jest wydawany po stronie klienta.
— matteo

2
Sztuczka jsonp prawdopodobnie już nie działa, fyi: stackoverflow.com/questions/12216208/...
— Drawww

7
Uwaga, ponieważ właśnie zmarnowałem pół dnia na ściganie tego błędu - jeśli skrypt po stronie serwera zawiedzie z wewnętrznym błędem serwera, przeglądarka może zinterpretować go tak, jakby żądanie nie było dozwolone z powodu Access-Control-Allow-Origini zgłosić to jako błąd.
— troelskn

1
@troelskn Właśnie uratowałeś mi życie. Szukałem błędu CORS od 3 dni i był to po prostu mały problem z konfiguracją wiosenną, powodujący 500, który rozwiązałem w 5 minut po przeczytaniu twojego komentarza i faktycznie go szukałem. Dziękuję Ci!
— Alexis Dufrenoy

Odpowiedzi:


378

Niedawno napisałem artykuł na ten temat, Cross Domain AJAX .

Najłatwiejszym sposobem poradzenia sobie z tym, jeśli masz kontrolę nad serwerem odpowiadającym, jest dodanie nagłówka odpowiedzi dla:

Access-Control-Allow-Origin: *

Umożliwi to Ajax między domenami . W PHP będziesz chciał zmodyfikować odpowiedź w następujący sposób:

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

Możesz po prostu umieścić to Header set Access-Control-Allow-Origin *ustawienie w Apache konfiguracji lub pliku htaccess.

Należy zauważyć, że to skutecznie wyłącza ochronę CORS, co bardzo prawdopodobne naraża użytkowników na atak . Jeśli nie wiesz, że konkretnie potrzebujesz użyć symbolu wieloznacznego, nie powinieneś go używać, a zamiast tego powinieneś dodać białą listę do swojej konkretnej domeny:

<?php header('Access-Control-Allow-Origin: http://example.com') ?>

4
Skontaktuję się z dostawcą mojego serwera. Dzięki
— Ricardo,

8
Czy są z tym jakieś obawy związane z bezpieczeństwem? Ta odpowiedź mówi na przykład: „JavaScript jest ograniczony przez„ zasady tego samego pochodzenia ”ze względów bezpieczeństwa, na przykład złośliwy skrypt nie może skontaktować się ze zdalnym serwerem i wysłać poufnych danych z Twojej witryny”.
— JohnK

4
Wspaniale, właśnie wstawiłem to do pliku serwera node.js: response.writeHead (200, {„Content-Type”: contentType, „Access-Control-Allow-Origin”: „*”}); I zadziałało. Dzięki!
— vbullinger

25
JohnK, tak, symbol wieloznaczny pozwoli dowolnej domenie na wysyłanie żądań do twojego hosta. Zalecam zastąpienie gwiazdki określoną domeną, na której będą uruchamiane skrypty.
— Nick

7
Interesujące jest to, że uważasz, że symbol wieloznaczny nie powinien nawet być sugerowany @jfrej. Wszystko zależy od twojego celu. Na przykład użyliśmy symbolu wieloznacznego (i opublikowaliśmy tę odpowiedź), ponieważ budowaliśmy wbudowany widget dla dowolnej witryny.
— Matt Mombrea

63

Jeśli nie masz kontroli nad serwerem, możesz po prostu dodać ten argument do programu uruchamiającego Chrome:--disable-web-security .

Pamiętaj, że nie użyłbym tego do normalnego „surfowania po Internecie”. W celach informacyjnych zobacz ten post: Wyłącz tę samą zasadę pochodzenia w Chrome .

Jeśli użyjesz Phonegap do zbudowania aplikacji i załadowania jej na urządzenie, nie będzie to problemem.


Dzięki. Ale moja aplikacja działa na urządzeniach mobilnych, nie mogę przekazywać argumentów do opakowania WebView.
— Ricardo

Czy najpierw nie testujesz aplikacji w przeglądarce? Jak debugujesz?
— Travis Webb,

Tak, debuguję w przeglądarce Chrome, ale aplikacja nie działa na Chrome. Będzie to na widoku sieci telefonicznej, którego nie mogę kontrolować.
— Ricardo

4
przeczytaj odpowiedź: możesz po prostu dodać ten argument do programu uruchamiającego Chrome . W Chrome nie ma takiego ustawienia
— Travis Webb

2
Oczywiście to niepewne. OP prosi o obejście środków bezpieczeństwa.
— Travis Webb,

42

Jeśli używasz Apache, po prostu dodaj:

<ifModule mod_headers.c>
    Header set Access-Control-Allow-Origin: *
</ifModule>

w twojej konfiguracji. Spowoduje to, że wszystkie odpowiedzi z twojego serwera będą dostępne z dowolnej innej witryny w Internecie. Jeśli zamierzasz zezwolić, aby usługi na Twoim hoście były używane tylko przez określony serwer, możesz zastąpić *adresem URL serwera źródłowego:

Header set Access-Control-Allow-Origin: http://my.origin.host

3
I nie zapomnij załadować modułu: nagłówki a2enmod
— Walery Strauch,

jak załadować moduł: nagłówki a2enmod?
— Ayesha,

18

Jeśli masz aplikację ASP.NET / ASP.NET MVC , możesz dołączyć ten nagłówek za pomocą pliku Web.config:

<system.webServer>
  ...

    <httpProtocol>
        <customHeaders>
            <!-- Enable Cross Domain AJAX calls -->
            <remove name="Access-Control-Allow-Origin" />
            <add name="Access-Control-Allow-Origin" value="*" />
        </customHeaders>
    </httpProtocol>
</system.webServer>

2
.NET MVC Ludzie, PATRZ tutaj! Zamierzam napisać rozwiązanie i wskazać tę odpowiedź na moim blogu, aby ludzie mogli łatwiej ją znaleźć. Nic gorszego niż próba pokonania przeszkody .NET / MVC i znalezienia niczego poza rozwiązaniami PHP / jQuery. Dzięki @ Caio-Proiete
— ottoflux

1
Dlaczego to nie działa dla mnie? Używam Chrome i próbuję uzyskać dostęp do strony finansów Yahoo z mojego lokalnego hosta.
— newman

1
dzięki, że zadziałało dla mnie. Dodałem w projekcie kodu po stronie serwera (web.config).
— ethem

15

To było pierwsze pytanie / odpowiedź, które pojawiło się dla mnie, gdy próbowałem rozwiązać ten sam problem za pomocą ASP.NET MVC jako źródła moich danych. Zdaję sobie sprawę, że to nie rozwiązuje PHP pytania , ale jest wystarczająco powiązane, aby być cennym.

Używam ASP.NET MVC. Blogu z Gregiem Brant pracował dla mnie. Ostatecznie tworzysz atrybut,[HttpHeaderAttribute("Access-Control-Allow-Origin", "*")] który możesz dodawać do akcji kontrolera.

Na przykład:

public class HttpHeaderAttribute : ActionFilterAttribute
{
    public string Name { get; set; }
    public string Value { get; set; }
    public HttpHeaderAttribute(string name, string value)
    {
        Name = name;
        Value = value;
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        filterContext.HttpContext.Response.AppendHeader(Name, Value);
        base.OnResultExecuted(filterContext);
    }
}

A następnie używając go z:

[HttpHeaderAttribute("Access-Control-Allow-Origin", "*")]
public ActionResult MyVeryAvailableAction(string id)
{
    return Json( "Some public result" );
}

1
WebApi 2 ma to teraz wbudowane. asp.net/web-api/overview/security/…
— Matt

10

Ponieważ Matt Mombrea jest poprawny po stronie serwera, możesz napotkać inny problem, którym jest odrzucenie białej listy.

Musisz skonfigurować phonegap.plist. (Używam starej wersji phonegap)

W przypadku Kordowa mogą wystąpić pewne zmiany w nazwie i katalogu. Ale kroki powinny być w większości takie same.

Najpierw wybierz Pliki pomocnicze> PhoneGap.plist

wprowadź opis zdjęcia tutaj

następnie w „ExternalHosts”

Dodaj wpis o wartości „ http://nqatalog.negroesquisso.pt ” Używam * tylko do celów debugowania.

wprowadź opis zdjęcia tutaj


8

Może to być przydatne dla każdego, kto potrzebuje wyjątku zarówno dla wersji strony odsyłającej „www”, jak i „innej niż www”:

 $referrer = $_SERVER['HTTP_REFERER'];
 $parts = parse_url($referrer);
 $domain = $parts['host'];

 if($domain == 'google.com')
 {
         header('Access-Control-Allow-Origin: http://google.com');
 }
 else if($domain == 'www.google.com')
 {
         header('Access-Control-Allow-Origin: http://www.google.com');
 }

Wskazał mi właściwy kierunek w rozwiązaniu błędu ACAO za pomocą lazuru. Podczas gdy dodałem dozwoloną nazwę hosta googledrive. Używany adres URL musi być googledrive NIE googledrive
— Kildareflare

7

Dam ci proste rozwiązanie tego problemu. W moim przypadku nie mam dostępu do serwera. W takim przypadku możesz zmienić zasady bezpieczeństwa w przeglądarce Google Chrome, aby zezwolić na Access-Control-Allow-Origin. To jest bardzo proste:

  1. Utwórz skrót przeglądarki Chrome
  2. Kliknij prawym przyciskiem myszy ikonę skrótu -> Właściwości -> Skrót -> Cel

Proste wklejanie "C:\Program Files\Google\Chrome\Application\chrome.exe" --allow-file-access-from-files --disable-web-security.

Lokalizacja może się różnić. Teraz otwórz Chrome, klikając ten skrót.



6

Jeśli piszesz Chrome Extension i dostać ten błąd, a następnie upewnij się, że zostały dodane bazowy URL API do swojej manifest.json„s uprawnienia blok , na przykład:

"permissions": [
    "https://itunes.apple.com/"
]


6

jeśli korzystasz z Apache, po prostu dodaj plik .htaccess do katalogu z tą zawartością:

Header set Access-Control-Allow-Origin: *

Header set Access-Control-Allow-Headers: content-type

Header set Access-Control-Allow-Methods: *

5

W Ruby on Rails możesz zrobić w kontrolerze:

headers['Access-Control-Allow-Origin'] = '*'

w jakim kontrolerze umieścisz to, jeśli jest to wywołanie ajax? Czy mogę zobaczyć więcej kontekstu kodu?
— rigdonmr

5

Możesz sprawić, aby działał bez modyfikowania serwera, tworząc broswer zawierający nagłówek Access-Control-Allow-Origin: * w odpowiedziach OPCJI HTTP.

W Chrome użyj tego rozszerzenia . Jeśli korzystasz z Mozilli, sprawdź tę odpowiedź .


5

Jeśli otrzymujesz to w Angular.js, upewnij się, że nie masz numeru portu:

var Project = $resource(
    'http://localhost\\:5648/api/...', {'a':'b'}, {
        update: { method: 'PUT' }
    }
);

Zobacz tutaj, aby uzyskać więcej informacji na ten temat.


4

Mamy również ten sam problem z aplikacją phonegap testowaną w chromie. Jedna maszyna z systemem Windows, której używamy codziennie poniżej pliku wsadowego przed otwarciem Chrome. Pamiętaj, że przed uruchomieniem tego musisz wyczyścić wszystkie wystąpienia chrome z menedżera zadań lub możesz wybrać chrome, aby nie działał w tle.

SERIA: (użyj cmd)

cd D:\Program Files (x86)\Google\Chrome\Application\chrome.exe --disable-web-security


0

Po otrzymaniu prośby możesz

var origin = (req.headers.origin || "*");

niż kiedy musisz odpowiedzieć, idź z czymś takim:

res.writeHead(
    206,
    {
        'Access-Control-Allow-Credentials': true,
        'Access-Control-Allow-Origin': origin,
    }
);
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.