I have a set up a Django server and want to access it by a Phonegap application using ajax. This works well so far. Now I try to upload a file to the server, but I am getting status code 403 FORBIDDEN.
I think this is because I use a form to upload the file and csrf does not work right.
The csrf token is pulled on login:
def login(request): ... response = { ... csrf : get_new_csrf_key() } return HttpResponse(json.dumps(response), content_type= json )
and stored in public R.user.csrf
Server upload view:
from django.middleware.csrf import _get_new_csrf_key as get_new_csrf_key from django.middleware.csrf import CsrfViewMiddleware ... def uploadfile(request): ... if request.is_ajax(): form = UploadForm(request.POST, request.FILES) u_file = request.FILES[ upload ] extension = u_file.name.split(".")[-1] upload = File( data = u_file, owner = user, fileid = newfid, name = newfile , description = u_file.name, createdat = timezone.now(), type = extension ) upload.save() response = { head : Success , message : Filed uploaded! , time : 3000 , fileid : newfid } return HttpResponse(json.dumps(response), content_type= json )
Application ajax call:
var uploadFile = function(){ console.log( uploading file... ); updateLoader(1); var selectFile = $( #selectfile ); var file = new FormData($( #uploadForm )[0]); var request = $.ajax({ type : "POST", url : R.urls.uploadfile, data : { file : file, csrfmiddlewaretoken : R.user.csrf }, processData : false, contentType : false, error : function(response) { console.log( upload failed! ); updateLoader(-1); showMessage("Failed", "Something went wrong...", 3000); selectFile.replaceWith(selectFile = selectFile.clone(true)); }, success : function(data) { console.log( upload successful! ); updateLoader(-1); var filename = $( #filename ).val(); var parent = $( #parentfolder ).val(); sendReRequest(data.fileid, filename, parent); selectFile.replaceWith(selectFile = selectFile.clone(true)); } }); };
HTML:
<input class="inputfield" type="text" id="parentfolder" name="parentfolder"><br/> <input class="inputfield" type="text" id="filename" name="filename" placeholder="Give your file a name"><br/> <form id="uploadForm" method="post" enctype="multipart/form-data"> <input class="inputfield" id="selectfile" type="file" name="upload"><br/> <input id="uploadfilebutton" type="submit" value="Upload" /> </form>
I also tried:
var csrfSafeMethod = function(method) { // these HTTP methods do not require CSRF protection return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); }; $.ajaxSetup({ beforeSend: function(xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) { xhr.setRequestHeader("X-CSRFToken", R.user.csrf); } } });
What do I miss? Thanks!