このPOSTビューにangular.jsを使用してDjangoリクエストを作成しようとしています。
class PostJSON4SlickGrid(View):
"""
REST POST Interface for SlickGrid to update workpackages
"""
def post(self, request, root_id, wp_id, **kwargs):
print "in PostJSON4SlickGrid"
print request.POST
return HttpResponse(status=200)
したがって、このリソースを作成しました。
myModule.factory('gridData', function($resource) {
//define resource class
var root = {{ root.pk }};
return $resource('{% url getJSON4SlickGrid root.pk %}:wpID/', {wpID:'@id'},{
get: {method:'GET', params:{}, isArray:true},
update:{method:'POST'}
});
});
コントローラーでgetメソッドを呼び出すと正常に動作します。 URLはhttp://127.0.0.1:8000/pm/rest/tree/1/
に翻訳されます。
function gridController($scope, gridData){
gridData.get(function(result) {
console.log(result);
$scope.treeData = result;
//broadcast that asynchronous xhr call finished
$scope.$broadcast('mySignal', {fake: 'Hello!'});
});
}
Update/POSTメソッドの実行に関する問題に直面している間。
item.$update();
URLはhttp://127.0.0.1:8000/pm/rest/tree/1/345
に変換され、末尾にスラッシュがありません。 URL定義で末尾のスラッシュを使用しない場合、これは簡単に回避できます。
url(r'^rest/tree/(?P<root_id>\d+)/(?P<wp_id>\d+)$', PostJSON4SlickGrid.as_view(), name='postJSON4SlickGrid'),
の代わりに
url(r'^rest/tree/(?P<root_id>\d+)/(?P<wp_id>\d+)/$', PostJSON4SlickGrid.as_view(), name='postJSON4SlickGrid'),
末尾にスラッシュを付けずに回避策を使用すると、403(禁止)ステータスコードが表示されます。これは、おそらく [〜#〜] csrf [〜#〜] トークンをPOST request。したがって、私の質問は、CSRFトークンをPOST angularによって作成されたリクエストに渡す方法を教えてください。
ヘッダーを介してcsrfトークンを渡す this アプローチについて知っていますが、投稿リクエストの本文にトークンを追加する可能性を探しています、推奨通り ここ 。 angularでpostリクエストの本文にデータを追加することは可能ですか?
追加の読みとして、リソースに関するこれらの議論、削除された末尾のスラッシュ、およびリソースが現在持っている制限 disc1 および disc2 を見ることができます。議論の1つで、著者の1人は現在リソースを使用せず、代わりに this アプローチを使用することを推奨しています。
次のような電話をかけることはできません:
$http({
method: 'POST',
url: url,
data: xsrf,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
data
は、渡したいものにすることができ、それに&{{csrf_token}}
を追加するだけです。
リソースparams:{}
で、params
内にcsrfmiddlewaretoken:{{csrf_token}}
を追加してみてください
編集:
あなたはリクエストボディにデータを渡すことができます
item.$update({csrfmiddlewaretoken:{{csrf_token}}})
ヘッダーとして
var csrf = '{{ csrf_token }}';
update:{method:'POST', headers: {'X-CSRFToken' : csrf }}
文書化されていません issue
私はこれが1年以上前のものであることを知っていますが、誰かが同じ問題に遭遇した場合、angular JSにはすでにCSRF Cookieフェッチメカニズム(AngularJSのバージョン1.1.5以降)があり、 angular Djangoが使用するCookieの名前と、サーバーとの通信に使用するHTTPヘッダーも教えてください。
そのためにモジュール構成を使用します。
var app = angular.module('yourApp');
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
}]);
これで、すべてのリクエストが正しいDjango CSRFトークンになります。私の意見では、両方のフレームワーク(DjangoとDjangoの組み込みシステムを使用しているため、手動でトークンを配置するよりもはるかに正しいです。 angularJS)。
最近のangularjsバージョンでは、解決策が機能していません。だから私は以下を試しました
まず、マークアップにDjangoタグ{%csrf_token%}を追加します。
アプリの構成ファイルに$ httpインスペクターを追加する
angular.module('myApp').config(function ( $httpProvider) {
$httpProvider.interceptors.Push('myHttpRequestInterceptor');
});
angular.module("myApp").factory('myHttpRequestInterceptor', function ( ) {
return {
config.headers = {
'X-CSRFToken': $('input[name=csrfmiddlewaretoken]').val() }
}
return config;
}};
});
x-CSRFTokenをすべてのangularリクエストに追加します
最後に、Djangoミドルウェア "Django.middleware.csrf.CsrfViewMiddleware '"を追加する必要があります。これにより、CSRFの問題が解決します
私はこれを使います:
Djangoビュー:
@csrf_protect
def index(request):
#Set cstf-token cookie for rendered template
return render_to_response('index.html', RequestContext(request))
App.jsの場合:
(function(A) {
"use strict";
A.module('DesktopApplication', 'ngCookies' ]).config(function($interpolateProvider, $resourceProvider) {
//I use {$ and $} as Angular directives
$interpolateProvider.startSymbol('{$');
$interpolateProvider.endSymbol('$}');
//Without this Django not processed urls without trailing slash
$resourceProvider.defaults.stripTrailingSlashes = false;
}).run(function($http, $cookies) {
//Set csrf-kookie for every request
$http.defaults.headers.post['X-CSRFToken'] = $cookies.csrftoken;
$http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
});
}(this.angular));
正しいリクエストを送信するには、オブジェクトをparam-formに変換する必要があります。
$http.post('/items/add/', $.param({name: 'Foo'}));//Here $ is jQuery
var app = angular.module('angularFoo', ....
app.config(["$httpProvider", function(provider) {
provider.defaults.headers.common['X-CSRFToken'] = '<<csrftoken value from template or cookie>>';
}])