2015-05-15 8 views
56

Próbuję zaktualizować/wstawić dane w bazie danych MySQL za pośrednictwem zaplecza PHP. Buduję interfejs z AngularJS i korzystam z usługi $http do komunikacji z interfejsem API REST.

Moja konfiguracja wygląda następująco:

mam ustawienie nagłówka poprzez $ httpProvider:

$httpProvider.defaults.withCredentials = true; 
$httpProvider.defaults.headers = {'Content-Type': 'application/json;charset=utf-8'}; 

I POST-Call wygląda następująco:

return $http({ 
     url: url, 
     method: "POST", 
     data: campaign 
    }); 

Konsola programisty w Chrome pokazuje mi to:

enter image description here

Kiedy zmienić POST PUT, wyślę e opcji call zamiast PUT. A typ zawartości przełącza się tylko na content-type.

Moja prośba ładowność jest wysłać jako obiekt:

enter image description here

Jak mogę ustawić nagłówek prawidłowo?


EDIT:

PHP backend ustawia niektóre nagłówki:

$e->getResponse() 
       ->getHeaders() 
       ->addHeaderLine('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); 

    $e->getResponse() 
       ->getHeaders() 
       ->addHeaderLine('Access-Control-Allow-Origin', '*'); 

jest coś brakuje?

+0

Aplikacja/json to domyślny zestaw typu zawartości. Musisz wyszukać w swoim kodzie, jeśli gdzieś ustawiasz go na tekst/zwykły – Chandermani

+0

@Chandermani Mój kod jest dość mały. Mam jeden plik api.js, w którym to robię, oraz jeden plik .config.js, w którym ręcznie ustawiam nagłówek. –

+0

Zgadzam się z consensus. Twoje nagłówki nie powinny być potrzebne. Dzieje się coś bardzo dziwnego. Przeglądam wszystkie "http.post", które napisałem w Angular i wszystkie były proste. Przyjęto nagłówki. –

Odpowiedz

64

Ok, rozwiązałem to.

W czym problem?
CORS workflow dla DELETE, PUT i POST jest następujący:

enter image description here

co robi, jest:

  1. Kontrola który wniosek jest zamiar być
  2. Jeśli to POST , PUT lub DELETE
  3. Wysyła najpierw żądanie OPTION, aby sprawdzić, czy domena, z której wysyłane jest żądanie, jest taka sama, jak domena z serwera.
  4. jeśli nie, chce Access-Header aby móc wysłać tę prośbę

znaczenie: Żądanie OPCJE nie wysyła poświadczenia.

Tak więc mój serwer zaplecza zablokował żądanie PUT.

Rozwiązanie:
Wyrażając to w pliku

RewriteCond %{REQUEST_METHOD} OPTIONS 
RewriteRule ^(.*)$ blank.php [QSA,L] 
Header set Access-Control-Allow-Origin "http://sub.domain:3000" 
Header always set Access-Control-Allow-Credentials "true" 
Header always set Access-Control-Max-Age "1000" 
Header always set Access-Control-Allow-Headers "X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token, Accept-Encoding" 
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT" 

Po tym .htaccess, utworzyć pusty plik o nazwie .php blank.php wewnątrz folderu publicznego.

EDYCJA: Jak zauważył jeden z komentatorów, zamiast tworzyć pusty plik PHP, możesz dodać tę regułę przepisywania do pliku .htaccess \;

RewriteRule ^(.*)$ $1 [R=200,L,E=HTTP_ORIGIN:%{HTTP:ORIGIN}]] 

Dla wyjaśnienia:

  1. już wysłane Access-Control-header
  2. Co to rozwiązane było pierwsze dwie linie, a
  3. Access-Control-Allow-Origin z konkretnej subdomeny z Portem

Najlepsza strona internetowa, jaką mogłem znaleźć na learn more about CORS.

+0

Zamiast tworzyć puste.php, możemy użyć tego 'RewriteRule^(.*) 1 $ [R = 200, L, E = HTTP_ORIGIN:% {HTTP: ORIGIN}]] ' – rajagopalx

+0

Dzięki @gruberb. Twoje informacje pomogły mi zrozumieć, dlaczego dostałem OPTION zamiast POST. – Velidan

+0

Gratulacje. Nigdy nie widziałem tak pełnego wyjaśnienia CORS, jak to. – jprivillaso

3

Nie trzeba określić swoje nagłówki $http ręcznie, to wszystko zrobić dla ciebie za kulisami i są automatycznie ustawiane na application/json dla POST i PUT żądań typu. Wszystko, co powinieneś zrobić, to:

$http.post(url, data); 
$http.put(url, data); 
+2

Usunąłem go, ale potem wysyłam wywołanie OPTIONS zamiast PUT/POST. Jeśli je ustawię, przynajmniej wysyłam właściwe połączenie. –

+1

@gruberb, powinieneś próbować przeczytać ten artykuł: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS –

+1

@PhilippAndreychev Dzięki! Zaktualizowałem swoją odpowiedź. –

Powiązane problemy