Ich versuche, eine POST -Anforderung mithilfe von angle.js für diese Django-Ansicht zu erstellen.
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)
Deshalb habe ich diese Ressource erstellt.
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'}
});
});
Das Aufrufen der get -Methode in einem Controller funktioniert einwandfrei. Die URL wird in http://127.0.0.1:8000/pm/rest/tree/1/
übersetzt.
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!'});
});
}
Während ich Probleme habe, die Update-/POST-Methode auszuführen.
item.$update();
Die URL wird in http://127.0.0.1:8000/pm/rest/tree/1/345
übersetzt, dem ein nachstehender Schrägstrich fehlt. Dies kann leicht umgangen werden, wenn in Ihrer URL-Definition kein nachstehender Schrägstrich verwendet wird.
url(r'^rest/tree/(?P<root_id>\d+)/(?P<wp_id>\d+)$', PostJSON4SlickGrid.as_view(), name='postJSON4SlickGrid'),
anstatt
url(r'^rest/tree/(?P<root_id>\d+)/(?P<wp_id>\d+)/$', PostJSON4SlickGrid.as_view(), name='postJSON4SlickGrid'),
Mit der Problemumgehung ohne den nachgestellten Schrägstrich bekomme ich jetzt einen 403 (Forbidden) Statuscode, der wahrscheinlich darauf zurückzuführen ist, dass ich in der Anforderung POST kein CSRF token übergeben habe. Daher läuft meine Frage darauf aus, wie ich das CSRF-Token in die von <wink> erstellte Anforderung POST übergeben kann.
Ich weiß über this Ansatz, um das CSRF-Token über die Header zu übergeben, aber ich suche nach einer Möglichkeit, das Token zum Body der Post-Anfrage hinzuzufügen, wie vorgeschlagen hier . Ist es in eckig möglich, Daten zum Post-Request-Body hinzuzufügen?
Als zusätzliche Lesung kann man sich diese Diskussionen über Ressourcen ansehen, nachfolgende Schrägstriche entfernen und die Ressourcen mit Einschränkungen derzeit haben: disc1 und disc2 ..__ In einer der Diskussionen empfiehlt einer der Autoren derzeit Verwenden Sie keine Ressourcen, sondern verwenden Sie stattdessen this .
Kannst du nicht so telefonieren:
$http({
method: 'POST',
url: url,
data: xsrf,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
Die data
kann beliebig sein, und Sie fügen einfach &{{csrf_token}}
hinzu.
Versuchen Sie in Ihrer Ressource params:{}
, csrfmiddlewaretoken:{{csrf_token}}
in der params
hinzuzufügen.
Bearbeiten:
Sie können Daten an den Anforderungstext als übergeben
item.$update({csrfmiddlewaretoken:{{csrf_token}}})
und zu Headern als
var csrf = '{{ csrf_token }}';
update:{method:'POST', headers: {'X-CSRFToken' : csrf }}
Es ist eine undokumentierte Ausgabe
Ich weiß, dass dies mehr als ein Jahr alt ist, aber wenn jemand auf dasselbe Problem stößt, verfügt eckige JS bereits über einen CSRF-Cookie-Abrufmechanismus (Versionen von AngularJS ab 1.1.5), und Sie müssen nur sagen, was der Name ist des Cookies, das Django verwendet, und auch den HTTP-Header, mit dem es mit dem Server kommunizieren soll.
Verwenden Sie dazu die Modulkonfiguration:
var app = angular.module('yourApp');
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
}]);
Jetzt hat jede Anfrage den richtigen Django CSRF-Token. Meiner Meinung nach ist dies viel richtiger als das manuelle Platzieren des Tokens bei jeder Anforderung, da er eingebaute Systeme aus beiden Frameworks (Django und AngularJS) verwendet.
In der letzten Version von anglejs funktioniert die Lösung nicht. Also habe ich folgendes versucht
Fügen Sie zunächst das Django-Tag {% csrf_token%} im Markup hinzu.
Fügen Sie Ihrer App-Konfigurationsdatei einen $ http-Inspector hinzu
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;
}};
});
es wird das X-CSRFToken in alle Winkelanfragen eingefügt
Als letztes müssen Sie die Django-Middleware "Django.middleware.csrf.CsrfViewMiddleware '" Hinzufügen. Dadurch wird das CSRF-Problem gelöst
Ich benutze das:
In der Django-Ansicht:
@csrf_protect
def index(request):
#Set cstf-token cookie for rendered template
return render_to_response('index.html', RequestContext(request))
In 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));
Um eine korrekte Anfrage zu senden, müssen Sie das Objekt in das param-Formular konvertieren
$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>>';
}])