私は基本的なAngularJSサービスを次のようにセットアップしています:
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'
}
}
});
});
そして私はそれを次のように使用します:
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);
});
問題1: User.update()は、メソッドがPOSTに設定されているにもかかわらず、リクエストメソッドとしてOPTIONSを送信し続けます。
Chrome開発ツールはリクエストヘッダーを報告しますが、Access-Control-Request-Method:POSTも送信されます(それが何かを意味するかどうかはわかりません)。
問題2: APIコードでこれらのヘッダーが設定されているにもかかわらず、CORSでエラーが発生し続けます。
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Methods: PUT, GET, POST, DELETE, OPTIONS");
この問題は、GET以外のリクエストを行った場合にのみ発生します。
これを処理する適切な方法は何ですか?私はJSONPも調べましたが、これはRESTful APIであるため、GETサポートのみで問題を回避する方法がわかりません。
あなたの2つの問題は実際には1つの問題です。 OPTIONSリクエストはCORSプロセスの一部です。 POSTリクエストの場合、ブラウザは最初にOPTIONS呼び出しを送信し、サーバーはそれを実行してもよいかどうか応答します。
OPTIONSリクエストが失敗した場合、Angular/Chromeはコンソールに理由を表示します。例:
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.
おそらくサーバーにもAccess-Control-Allowヘッダーを設定する必要があります。
header('Access-Control-Allow-Headers: Content-Type, x-xsrf-token')
x-xrsf-tokenは、CSRFを防止するためのAngular用です。クライアントから送信する内容によっては、ヘッダーを追加する必要がある場合があります。
CORSに関する非常に優れたガイドを次に示します。 https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS
AngularJSでCORSを機能させるには、angular httpProvider
のデフォルト設定も上書きする必要があります。
var myApp = angular.module('myApp', [
'myAppApiService']);
myApp.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}
]);
UseXDomainをtrueに設定するだけでは十分ではありません。 AJAXリクエストもX-Requested-Withヘッダーとともに送信され、AJAXであることを示します。ヘッダーを削除する必要があるため、サーバーは受信リクエストを拒否しません。
注:回答は1.2より前の古いAngularJSバージョンでのみ機能します。 1.2以降では、CORSを有効にするために何もする必要はありません。
サーバーでこの問題を解決する方がよい。 Apacheでは、.htaccess
ファイルでこのように解決できます。これはangular開発の痛みの原因であり、angularでも解決できますが、おそらくそれを行うための最良の方法ではありません。
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"