2013-06-25 13 views
16

Mam podstawowej konfiguracji usługi angularjs tak:angularjs: POST dane do zewnętrznych REST API

app.factory('User', function($resource) { 
return $resource('http://api.mysite.com/user/:action:id/:attr', {}, { 
    history: { 
     method: 'GET', 
     params: { 
      attr: 'history' 
     } 
    }, 
    update: { 
     method: 'POST', 
     params: { 
      name: 'test' 
     } 
    } 
}); 
}); 

i używam go tak:

User.history({id: 'testID'}, function(data) { 
    console.log('got history'); 
    console.log(data); 
}); 
User.update({id: 'me'}, function(data) { 
    console.log('updated'); 
    console.log(data); 
}); 

Problem pierwszy: User.update(), mimo że metoda jest ustawiona na POST, wysyła wysyłane OPCJE jako metodę żądania.

Chociaż narzędzia do Chrome Chrome zgłaszają nagłówek żądania Metoda kontroli dostępu do żądania: POST również jest wysyłana (nie wiem, czy to oznacza cokolwiek).

Problem drugi: Ciągle otrzymuję błąd z CORS, pomimo tych nagłówków określonych w kodzie API:

header('Access-Control-Allow-Origin: *'); 
header("Access-Control-Allow-Methods: PUT, GET, POST, DELETE, OPTIONS"); 

Problem ten pokazuje tylko, choć jeśli dokonywania non-GET żądania.

Jaki jest właściwy sposób obsługi tego? Zajrzałem również do JSONP, ale z tym, że jest to aplet RESTful, nie jestem pewien, jak obejść problemy tylko z obsługą GET.

Odpowiedz

14

Twoje dwa problemy to właściwie jeden problem. Żądanie OPCJE jest częścią procesu CORS. W przypadku żądań POST przeglądarka wysyła najpierw wywołanie OPTIONS, a serwer odpowiada, czy można go uruchomić.

Jeśli żądanie OPCJE nie powiedzie się, Angular/Chrome pokazuje przyczynę na konsoli. Na przykład:

OPTIONS https://*** Request header field Content-Type is not allowed by Access-Control-Allow-Headers. angular.min.js:106 

XMLHttpRequest cannot load https://***. Request header field Content-Type is not allowed by Access-Control-Allow-Headers. 

Prawdopodobnie trzeba ustawić Access-Control-Allow nagłówki na serwerze, za:

header('Access-Control-Allow-Headers: Content-Type, x-xsrf-token') 

x-xrsf-żeton jest kanciasty”, aby zapobiec CSRF. Może być konieczne dodanie większej liczby nagłówków, w zależności od tego, co wyślesz od klienta.

Tutaj jest bardzo dobrym przewodnikiem na CORS: https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS

+0

Przeglądarka wysyłająca żądanie OPCJE, a następnie żądanie POST było moim problemem. Serwer nie został skonfigurowany, aby reagować na początkowe OPCJE. Nie musiałem jednak nic robić z użyciem tokena x-xsrf. Wykorzystano tutaj kod do obsługi wszystkich niezbędnych nagłówków: http://stackoverflow.com/questions/13293157/backbone-slim-php-access-control-allow-headers-can-get-information-cant/13530329#13530329 –

+1

to był dokładnie mój problem. Dziękuję Ci. Jeśli używasz węzła/ekspresu, postępuj zgodnie z instrukcjami "włącz przed lotem" tutaj, aby uzyskać pracę cors: https://github.com/troygoode/node-cors/ – JasonS

7

W angularjs zarabiania CORS pracy trzeba także nadpisać domyślne ustawienia kątowego httpProvider:

var myApp = angular.module('myApp', [ 
    'myAppApiService']); 

myApp.config(['$httpProvider', function($httpProvider) { 
     $httpProvider.defaults.useXDomain = true; 
     delete $httpProvider.defaults.headers.common['X-Requested-With']; 
    } 
]); 

Wystarczy ustawienie useXDomain true nie wystarcza. Żądanie AJAX jest również wysyłane z nagłówkiem X-Requested-With, który jest AJAX. Usunięcie nagłówka jest konieczne, aby serwer nie odrzucał przychodzącego żądania.

Uwaga: Odpowiedź działa tylko dla starszych wersji poprzedniej angularjs do 1,2. Z wersją 1.2 i wyższą nie musisz robić nic, aby umożliwić CORS.

+6

To faktycznie nie było konieczne, ponieważ mam dostęp do serwer api i dodano 'header ('Access-Control-Allow-Headers: X-Requested-With');' który, jak zakładam, rozwiązuje problem, o którym mówisz. –

+0

Dobra wskazówka. Nie wiedziałem o ustawieniu nagłówka nagłówków zezwalających. Dzięki. –

+0

Może musiałeś to zrobić ze starymi wersjami kątowymi, ale wiem, że w kanciastej wersji 1.2.x nie musisz tego robić. Po @ Odpowiedź Narretza działa dla mnie. – JasonS

0

Lepiej rozwiązać ten problem na serwerze. Na apache można to rozwiązać w ten sposób w pliku .htaccess. Jest to źródło bólu dla rozwoju kątowego i może być rozwiązane również kątowo, ale prawdopodobnie nie jest to najlepszy sposób na zrobienie tego.

Header set Access-Control-Allow-Origin "*" 
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type" 
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"