简体   繁体   English

Django - 从 javascript 发送 POST 请求

[英]Django - Sending POST request from javascript

I have a JS event-triggered function which goal is send a POST request in order to update some objects in my database.我有一个 JS 事件触发的 function,其目标是发送 POST 请求以更新数据库中的某些对象。 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.触发 function 的事件是一个丢弃事件,所以我最初避免使用 forms 来传递我的请求,但如果我做错了,请告诉我。

Big Edit:大编辑:

I found that my mistake was to not include the csrf_token on my post request.我发现我的错误是没有在我的发布请求中包含 csrf_token。 However, i still have an error: my post request comes in empty when i do print(request.POST) on my django view.但是,我仍然有一个错误:当我在 django 视图上执行print(request.POST)时,我的发布请求为空。

My JS file:我的 JS 文件:

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.当我这样做时,request.POST 的查询字典为空。 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.但是,如果我将Content-Type header 更改为application/x-www-form-urlencoded ,则该请求有效,但它将所有内容放在同一个键上。

Example:例子:

Result with 'application/json': 'application/json' 的结果:

<QueryDict: {}>

Result with 'application/x-www-form-urlencoded': '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..无论如何,我认为“应用程序/json”应该可以工作,但我不知道为什么它不..

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).因此,您首先需要对站点进行身份验证/登录(也许使用另一个 Ajax 调用)。 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.如果站点支持 jwt/api 身份验证,您将获得一个令牌,您必须在下一个(发布)请求中将其与 header 一起发送。 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.如果站点使用会话/cookie 身份验证,那么我建议考虑使用 jQuery 及其 Ajax 功能。 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如果你想以 application/json 的形式获取数据,你必须查看请求的正文

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

this would give you a byte object.这会给你一个字节 object。 you have load it to a json if you want json.如果您想要 json,您已将其加载到 json。 request.POST is only for Content-Type 'application/x-www-form-urlencoded' request.POST仅适用于 Content-Type 'application/x-www-form-urlencoded'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM