web-dev-qa-db-ja.com

AngularJS:POST Data to External REST API

私は基本的な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サポートのみで問題を回避する方法がわかりません。

16
Lucas Raines

あなたの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

14
Narretz

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を有効にするために何もする必要はありません。

7

サーバーでこの問題を解決する方がよい。 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"
0
rotato poti