2013-07-09 19 views
17

Piszę API i używam Laravel 4, aby to osiągnąć. Moje API znajduje się w innej domenie. Załóżmy, że jest: http://api-example.com/CORS z Laravel 4

A gdy próbuję wykonać żądania ajax przez Backbone do mojego api z mojej aplikacji internetowej (tj. mydomain.com) z podstawowym uwierzytelnieniem, czasami działa dobrze, ale czasami tak nie jest. Próbuję zrozumieć dlaczego. Poniżej znajduje się mój filtr App::before i filtr App::after.

App::before(function($request) 
{ 
    if($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { 
     $statusCode = 204; 

     $headers = [ 
      'Access-Control-Allow-Origin'  => 'http://mydomain.com', 
      'Allow'       => 'GET, POST, OPTIONS', 
      'Access-Control-Allow-Headers'  => 'Origin, Content-Type, Accept, Authorization, X-Requested-With', 
      'Access-Control-Allow-Credentials' => 'true' 
     ]; 

     return Response::make(null, $statusCode, $headers); 
    } 
}); 

i My po filtrze:

App::after(function($request, $response) 
{ 
    $response->headers->set('Access-Control-Allow-Origin', 'http://mydomain.com'); 
    $response->headers->set('Allow', 'GET, POST, OPTIONS'); 
    $response->headers->set('Access-Control-Allow-Headers', 'Origin, Content-Type, Accept, Authorization, X-Requested-With'); 
    $response->headers->set('Access-Control-Allow-Credentials', 'true'); 
    return $response; 
}); 

Chodzi o to, kiedy próbuję zrobić żądania POST do /login z poświadczeniami, API sprawdza db i dostaje klucz API dla użytkownika. To działa dobrze. Ale gdy próbuję wykonać żądanie POST do /users chromem po prostu daje mi następujący błąd:

XMLHttpRequest cannot load http://api-example.com/users. Origin http://mydomain.com is not allowed by Access-Control-Allow-Origin. 

Próbowałem wszystkiego, takie jak ustawienie Access-Control-Allow-Origin do '*' wszystko mogę być w stanie znaleźć z internecie. Ale nic nie zadziałało tak daleko. Nie wiem, co powinienem zrobić.

+1

Sprawdzanie sieci za pomocą narzędzi Chrome Dev Tools pokazuje, że jest tam (czy nie)? –

+0

Dowolna operacja, która nie jest dostępna, najpierw wykonuje żądanie "przed lotem" OPCJONALNOŚCI - jak to wygląda na pewno. Upewnij się, że twój filtr przed uruchomieniem działa, nawet jeśli nie ma trasy, która by pasowała. Czy próbujesz też użyć polecenia PUT lub DELETE? Twoje nagłówki nie pozwalają na to. Wreszcie, pochodzenie "*" nie może być używane z autoryzacją. Właściwie, ostatnia uwaga: jak wygląda twoje żądanie Ajax? jQuery ma ustawienie wysyłania żądań z autoryzacją. – fideloper

+0

Nie sądzę, że nagłówki są ustawione. Zamiast '$ response-> headers-> set()' try 'header ('Zezwalaj: GET, POST, OPCJE')' może działać –

Odpowiedz

0

Niektóre przeglądarki mogą temu zaprzeczyć, ponieważ skrypty XSS robią paskudne rzeczy w ten sposób.

Jeśli wczytać plik js z http://api-example.com/ może pomóc, ale są bardziej stabilne rozwiązania:

  • Można użyć curl (lub coś podobnego) lub
  • Można korzystać z serwera proxy (Apache, Nginx itp) na żądanie AJAX do załadowania odpowiedź z innego hosta
  • albo jeśli useing równoważenia obciążenia lub frontend cache'owanie rzeczy, można utworzyć regułę ...

To de zależy od twojej infrastruktury i potrzeb, ale jeśli wydajność ma znaczenie, pomiń curl.

+0

Przykro mi, ale jestem naprawdę początkującym specjalistą od rzeczy związanych z load balancer, czy możesz wyjaśnić szczegółowo, czy jest to dla ciebie w porządku? Ponieważ używam Amazon ELB do równoważenia obciążenia i nie znam znaczenia "tworzenia reguły". –

3

Nie ma sensu tworzenie wyszukanego obiektu odpowiedzi i zwracanie go, a następnie zezwolenie na procesowanie strony, ponieważ spowoduje to zatarcie nagłówków CORS i kontynuowanie zwykłej zawartości.

App::before(function($request) 
{ 
    if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { 

     header('Access-Control-Allow-Origin', 'http://mydomain.com'); 
     header('Allow', 'GET, POST, OPTIONS'); 
     header('Access-Control-Allow-Headers', 'Origin, Content-Type, Accept, Authorization, X-Request-With'); 
     header('Access-Control-Allow-Credentials', 'true'); 

     exit; 
    } 
}); 
6

W nagłówku jest błąd.

+0

To jest faktyczny błąd. Robię to samo z prawidłową odpowiedzią RESPONSE i działa mi dobrze. @ umut-sirin – Raftalks