contentType
当我们使用form表单提交数据时,有一个enctype属性,默认情况下不写
此时我们提交数据时,会默认将数据以application/x-www-form-urlencoded的编码方式发送
该形式的数据为"k1=v1&k2=v2"格式,可以看成是一组组的键值对
但是当我们要发送图片等二进制文件时,上面的形式就无法实现了,此时我们会将enctype属性设置为form-data
这时我们就既可以发送键值对的数据,又可以发送较大的二进制文件了
同样,在使用ajax发送数据时,默认情况下,我们发送的get和post请求都是以application/x-www-form-urlencoded的编码方式发送的
但是我现在想要向后端发送一个json字符串形式的数据,该怎么办呢
这里我们就需要使用ajax里的contentType参数
<!DOCTYPE html><html lang="en"><head> ???<meta charset="UTF-8"> ???<meta http-equiv="X-UA-Compatible" content="IE=edge"> ???<meta name="viewport" content="width=device-width, initial-scale=1"> ???<title>Title</title> ???<script src="http://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js"></script></head><body><button class="json_send">send</button>{% csrf_token %}<script src="https://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.js"></script><script> ???$(".json_send").click(function () { ???????????$.ajax({ ???????????url:"/ajax_send/", ???????????data:JSON.stringify({"k1":"v1"}), ???????????type:"post", ???????????contentType:"application/json", ???????????success:function (data) { ???????????????console.log(data) ???????????} ???????});</script>
如果以上面的形式直接发送,我们会发现后端接收时,request.POST和request.GET内都取不到值
def ajax_send(request): ???import json ???print(request.GET) ?# <QueryDict: {}> ???print(request.POST) ?# <QueryDict: {}> ???print(request.body.decode()) ?# ?{"k1":"v1"}return HttpResponse("OK")
这就要从帮助Django处理http请求的wsgiref模块说起了
该模块主要做了三件事:
1.封装了一个socket对象,通过该对象与客户端建立连接
2.按照http协议解析数据
3.按照http协议封装响应数据
当该模块解析数据时,会有一定的规则
wsgi:if ?content_type: url_encoded: ???request.body :post(get)数据-------> request.POST(GET)
当数据格式为application/x-www-form-urlencoded时,他会把数据写到request.POST或者request.GET中,如果为其它格式,则不会,此时我们如果想拿到数据必须从request.body中取
这样我们就完成了json字符串格式的数据发送,但是我们注意到这里我们发送的是post请求,但是却未带csrftoken的相关数据,如果通过中间件的话,这个请求会被拒绝,那我们该如何将csrftoken的值一起发送过去呢
这里我们先研究一下csrftoken的中间件是如何取相应的值的
CsrfViewMiddleware: ???????????????if random_str=request.POST.get("csrfmiddlewaretoken") ????if ?random_str=="347289asd328": ????????pass ?elif request.META.get("X-CSRFToken"): ???????????????????????????request.META.get("X-CSRFToken")=="asdasdh23470ahsd37sa" ???else: ????return Htttpresponse("forbidden error")
我们发现中间件会先从request.POST中取,但是我们的数据不会被放到request.POST中,所以取不到
这时中间件又会从请求头部的X-CSRFToken中取值,如果还取不到,那么会forbidden
所以我们此时就要想办法将csrftoken的值放到请求头的X-CSRFToken中
其实每当我们发送一次请求时,我们会发现在我们的COOKIE中也会带有csrftoken的相关内容,此时就从中取值放入X-CSRFToken中
<script src="{% static ‘js/jquery.cookie.js‘ %}"></script> ?// 必须要引用,不然无法使用$.cookie方法$.ajax({ headers:{"X-CSRFToken":$.cookie(‘csrftoken‘)}, })
我们的代码为
$(".json_send").click(function () { ???????????????$.ajax({ ???????????url:"/ajax_send/", ???????????data:JSON.stringify({"k1":"v1"}), ???????????type:"post", ???????????headers:{"X-CSRFToken":$()}, ???????????contentType:"application/json", ???????????success:function (data) { ???????????????console.log(data) ???????????} ???????});
dataType
该属性表示我们期待服务器发送回来的数据是一个什么类型
如:dataType:json,表示我们期待服务器端发送的是一个json格式的数据
这个属性并不会改变服务器端的内容,但是当客户端拿到服务器端的数据后,ajax方法会将数据进行parser操作,得到我们想要的类型
error和complete
$(".send_Ajax").click(function(){ ??????????$.ajax({ ??????????????url:"/handle_Ajax/", ??????????????type:"POST", ??????????????data:{username:"Yuan",password:123}, ??????????????success:function(data){ ??????????????????alert(data) ??????????????}, ????????????????//=================== error============ ???????????????error: function (jqXHR, textStatus, err) { ???????????????????????// jqXHR: jQuery增强的xhr ???????????????????????// textStatus: 请求完成状态 ???????????????????????// err: 底层通过throw抛出的异常对象,值与错误类型有关 ???????????????????????console.log(arguments); ???????????????????}, ????????????????//=================== complete============ ???????????????complete: function (jqXHR, textStatus) { ???????????????????// jqXHR: jQuery增强的xhr ???????????????????// textStatus: 请求完成状态 success | error ???????????????????console.log(‘statusCode: %d, statusText: %s‘, jqXHR.status, jqXHR.statusText); ???????????????????console.log(‘textStatus: %s‘, textStatus); ???????????????},
我们使用success回调函数是在执行不出错时执行的,如果执行过程中出了错误,则会执行error的回调函数,而complete是不管出不出错都会执行的
ajax参数补充
原文地址:https://www.cnblogs.com/QQ279366/p/8494694.html