0

I have a JS event-triggered function which goal is send a POST request in order to update some objects in my database. The event which triggers the function is a drop-event, so i initially avoided using forms to pass my request, but tell me if i did wrong.

Big Edit:

I found that my mistake was to not include the csrf_token on my post request. However, i still have an error: my post request comes in empty when i do print(request.POST) on my django view.

My JS file:

function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = cookies[i].trim();
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}
var csrftoken = getCookie('csrftoken');

const dragDrop = function (e) {
    e.preventDefault()
    
    const droppedElId = e.dataTransfer.getData('Text/html').split('__id-')[1]
    const request = new XMLHttpRequest()
    request.open('POST', '', true)
    request.setRequestHeader('X-CSRFToken', csrftoken)
    request.setRequestHeader('Content-Type', 'application/json')
    // request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8')
    request.send(JSON.stringify({
        "request_name":"change-extra-fields",
        "type":"increase",
        "id":droppedElId,
    }))
}

The query-dict of the request.POST is empty when i do this. However, the request works if i change the Content-Type header to application/x-www-form-urlencoded, but it puts everything on the same key.

Example:

Result with 'application/json':

<QueryDict: {}>

Result with 'application/x-www-form-urlencoded':

<QueryDict: {'{"request_name":"change-extra-fields","type":"increase","id":"8"}': ['']}>

Anyways, i think that 'application/json' should be working and i have no idea why it isn't..

Ricardo Vilaça
  • 846
  • 1
  • 7
  • 18

1 Answers1

1

There is a typo I think

request.setRequestHeader('Content-Type', 'application/json');

As you mentioned in comments, your post request required you to be authenticated.

So, you first need to authenticate/login to the site(using another Ajax call perhaps). If the site supports jwt/api authentication you would get a token back which you have to send in attached with header in next (post)request. it would be something like this

xhr.setRequestHeader('Authorization', 'Bearer arandombereartoken');

if the site uses session/cookie authentication then I suggest consider using jQuery and its Ajax functions. I this this(2nd one) should be helpful.

UPDATE:

if you want to get data as application/json you have to look in the body of the request

if request.method == "POST":
        print(request.body)

this would give you a byte object. you have load it to a json if you want json. request.POST is only for Content-Type 'application/x-www-form-urlencoded'

mursalin
  • 1,151
  • 1
  • 7
  • 18
  • Unfortunately, the error doesn't come from the typo. But thanks :) I also tried to use the full url and it doesn't work. Also i don't think that it needs the full url because the console error goes like this: `POST http://myfullurl/mycurrentpage 403 (Forbidden)` – Ricardo Vilaça Jul 08 '20 at 15:26
  • 1
    is there any authentication required? – mursalin Jul 09 '20 at 05:32
  • Hmm yes. I need to be logged in to see the page i'm sending the request. I'm not sure if that's what you asked (it's my first web dev project, sorry if i don't understand).. Anyways, if that's the problem, what should i look for in order to fix it? Thanks – Ricardo Vilaça Jul 09 '20 at 08:51
  • @RicardoVilaça I have updated the answer, hope it would help. – mursalin Jul 09 '20 at 09:34
  • Hi @mursalin, so i've taking a look at other answers and finally understand the problem is that my post-request doesn't include the csrf_token. I tried your request header with the csrf_token but it still induces an error. There is an answer i found that doesn't do any error (i'll edit it on my original question), but still the request comes empty to Django. (When i print the request it's an empty dict). Do you know what it might be? – Ricardo Vilaça Jul 09 '20 at 10:54
  • 1
    @RicardoVilaça, glad to hear you have found the problem. I have updated the answer for your updated question. cheers! – mursalin Jul 09 '20 at 15:22
  • Thanks :) This will work for me right now. I thought there was a simpler way of sending information in QueryDict object like form elements usually do.. I think that in the future i'll need the information to come from request.POST and not request.body .. I'll open another thread to see if anyone knows how I'll mark this one as finished. Thank you – Ricardo Vilaça Jul 09 '20 at 16:08