私は現在、バックエンドにangularjsフロントエンドを書いていますが、やや一般的な問題に直面しています:
サーバーは応答でCookieを送り返しますが、angular.jsによって完全に無視されます(「Set-Cookie」値を出力することさえできません)。
読んでみた
AngularJSではHTTPヘッダーのSet-Cookieは無視されます
Angularjs $ httpは応答の「Set-Cookie」を理解していないようです
残念ながら、そこですべての解決策を試しましたが、うまくいかないようです。
リクエストを送信しました
受信した応答
Angular.js(v1.2.10)を使用していますが、これがリクエストの作成に使用したものです
$http.post('/services/api/emailLogin',
sanitizeCredentials(credentials),
{
withCredentials: true
}).success(function(data, status, header) {
console.log(header('Server'));
console.log(header('Set-Cookie'));
console.log(header('Access-Control-Allow-Headers'));
console.log(header('Access-Control-Allow-Methods'));
console.log(header);
}).then(
function(response) {
console.log(response);
return response.data;
});
withCredentials=true
は、リクエストを行う前にクライアント側で設定されます。
Access-Control-Allow-Credentials=true
は、応答を返す前にサーバー側で設定されます。
Set-Cookie
は、Chrome Developer Toolsからの応答ヘッダーにありますが、印刷は
応答ヘッダーのSet-Cookie
のみが出力されていません。なぜこれが起こるのだろうか? withCredentials=true
が実際に設定されていることを確認する方法はありますか(要求ヘッダーに表示されませんでした)。
どんな助けも大歓迎です!
$httpBackend
ソースコード:
xhr.onreadystatechange = function() {
// some code
if (xhr && xhr.readyState == 4) {
var responseHeaders = null,
response = null;
if(status !== ABORTED) {
responseHeaders = xhr.getAllResponseHeaders();
// some code
それは使用しています XMLHttpRequest#getAllResponseHeaders
応答ヘッダーを取得します。
少し検索した後、この質問を見つけました: xmlHttp.getResponseHeader + CORSで動作していません
そのため、XHRの仕様では、XHRはSET-COOKIE
なので、特にangle.jsとは関係ありません。
http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders%28%29-method
4.7.4 getAllResponseHeaders()メソッド
応答からすべてのヘッダーを返しますフィールド名がSet-CookieまたはSet-Cookie2のヘッダーを除く。
$cookies
:別のモジュールなので、スクリプトに追加する必要があります
<script src="angular.js"></script>
<script src="angular-cookies.js"></script>
そして、モジュールの依存関係に追加します:
var app = angular.module('app',['ngCookies']);
次に、次のように使用します。
app.controller('ctrl', function($scope, $http , $cookies, $timeout){
$scope.request = function(){
$http.get('/api').then(function(response){
$timeout(function(){
console.log($cookies.session)
});
})
}
})
私が使う $timeout
なぜなら$cookies
ダイジェスト後にのみブラウザのCookieと同期します。
あなたは実際にAngularでクッキーを読む必要がありますか、それが設定されてブラウザによるさらなるリクエストで返されれば十分ですか?前者を機能させることはできませんでしたが、非常に似た構成で後者をかなり迅速に機能させることができました。 (特に、@ Ilanが推奨するように$cookies
を使用できませんでした。何も返されませんでした。)
まず最初に、Angular側で$httpProvider
を設定して、デフォルトでwithCredentials
を送信します:
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.withCredentials = true;
}]);
Angularで行う必要があるのはそれだけです。この時点で、$cookies
を読み取ろうとすると、Cookieを見ることができませんが、保存され、将来のAJAX呼び出しで渡されます。
次に、サーバー上で、Access-Control-Allow-Credentials
ヘッダーとともに、CORSで許可されている特定のドメイン(またはドメインのセット)を提供する必要があります。私のバックエンドはFlask in Python with Flask-Restful であり、次のようになります。
import Flask
from flask_restful import Api
app = Flask(__name__)
api = Api(app)
api.decorators = [cors.crossdomain(Origin='http://localhost:8100', credentials=True)]
それだけで十分です。これでAngular(または、むしろブラウザ)がCookieを設定し、将来のリクエストで完全に透過的にそれを返します!
(同じポイントがここにあります: https://stackoverflow.com/a/19384207/2397068 。)
ヘッダーを読み取れるようにするには、.htaccessファイルを変更する必要があります。
Header set Access-Control-Allow-Headers Content-Type
Angular 1.3.14では動作しません。
同じ問題がありました。私は$ resourceを使用しており、withCredentials:trueと宣言しています。
var fooRes = $resource('/address/exemple',
{},
{
bar: {
method: 'POST',
withCredentials: true,
}
}
);
fooRes.bar({
"stuff" : "lorem"
}).$promise.then(function(){
//callback
})
または、ヘッダー「Access-Control-Allow-Credentials」、「true」を設定できます。
これでCookieが保存され、$ cookieを使用して取得できます。
それが役立つことを願っています。