2013-06-25 17 views
16

bir temel angularjs hizmet kurulumu şöyle var:angularjs: POST Veri Dış REST API için

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' 
     } 
    } 
}); 
}); 

ve ben bu gibi kullanmak:

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); 
}); 

Sorun tek: User.update(), POST olarak ayarlanan yönteme rağmen, istek yöntemi olarak OPTIONS göndermeye devam eder.

Chrome Dev araçları, istek başlığı Erişim Denetimi-İstek Yöntemi'ni rapor etmesine rağmen, POST da gönderilir (Bunun herhangi bir anlama gelip gelmediğinden emin olun).

Sorun iki: API kodunda belirlenen bu başlıkları olmasına rağmen, CORS bir hata almaya devam:

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

Bu sorun yalnızca olsa gösterir olmayan bir GET isteği yapan eğer.

Bunu işlemenin doğru yolu nedir? JSONP'a da baktım, ama bu RESTful api ile, sadece GET desteği ile sorunların nasıl giderileceğinden emin değilim.

cevap

14

İki probleminiz aslında bir problemdir. OPTIONS isteği CORS sürecinin bir parçasıdır. POST istekleri için, tarayıcı önce bir OPTIONS çağrısı gönderir ve sunucu yürütmenin tamam olup olmadığını yanıt verir.

OPTIONS isteği başarısız olursa, Angular/Chrome size konsolu neden gösterir. Örneğin:

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. 

Muhtemelen de sunucuda Başlıkları Erişim-Control-Allow ayarlamak zorunda:

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

x-xrsf-belirteç açısal içindir' CSRF önlemek için. İstemciden ne gönderdiğinize bağlı olarak daha fazla başlık eklemeniz gerekebilir. İşte

CORS üzerinde çok iyi bir kılavuzdur: https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS çalışma CORS'yi yapmak angularjs olarak

+0

OPTIONS isteğini gönderen tarayıcı daha sonra POST isteğim benim sorunumdu. Sunucu, ilk OPTIONS'a yanıt vermek üzere ayarlanmamış. Yine de x-xsrf-token ile bir şey yapmam gerekmedi. Gerekli tüm başlıkları ele almak için kodu buradan kullanın: http://stackoverflow.com/questions/13293157/backbone-slim-php-access-control-allow-headers-can-get-information-cant/13530329#13530329 –

+1

Bu tam olarak benim sorunumdu. teşekkür ederim. Düğüm/express kullanırsanız, korsanın çalışmasını sağlamak için "uçuş öncesi etkinleştir" talimatlarını izleyin: https://github.com/troygoode/node-cors/ – JasonS

7

da açısal httpProvider varsayılan ayarlarının üzerine zorunda:

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

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

Sadece true useXDomain ayarı yeterli değil. AJAX isteği de AJAX olarak belirttiği X-Talep-With başlığı ile göndermek vardır. Başlığı kaldırmak gereklidir, bu nedenle sunucu gelen isteği reddetmiyor.

Not: Cevap sadece 1.2 önceki eski angularjs sürümü için çalışır. 1.2 ve üstü ile CORS'i etkinleştirmek için hiçbir şey yapmanız gerekmez.

+6

Bu aslında gerekli değildi, api sunucusu ve head header ('Erişim-Kontrol-İzin-Başlıkları: X-Talep-Birlikte') eklendi; –

+0

İyi bir ipucu. İzin başlıklarının ayarlanmasından haberdar değildim. Teşekkürler. –

+0

belki de bunu eski açısal sürümleriyle yapmak zorundaydınız, ancak açısal 1.2.x'de bunu yapmanız gerekmediğini biliyorum. @ Narretz'in cevabı benim için çalışıyor. – JasonS

0

Bu sorunu sunucuda çözmek daha iyi. Apache'de bunu .htaccess dosyasında çözebilirsiniz. Bu açısal gelişim için bir ağrı kaynağıdır ve açısal olarak da çözülebilir, ancak muhtemelen bunu yapmanın en iyi yolu değildir.

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"