Django学习(6)http访问:request和response、GET和POST以及Ajax

request请求

http的请求主要使用POST和GET两种,GET直接把url写在地址栏里访问,而POST可以直接发送信息并可以发送文件。如果页面不需要跳转,只是给后端发送信息,务必使用POST。
在一个HttpRequest对象中,GET和 POST属性是的实例django.http.QueryDict[1],类似于字典的类的类经过自定义以处理同一键的多个值,因为某些HTML表单元素尤其是<select multiple>为同一键传递多个值。

request的常用属性和方法

属性 说明
HttpRequest.body 原始HTTP请求正文为字节串,而这个可以处理二进制图像,XML有效负载等。当前端使用Ajax,data = json.loads(r.body)可以解析JSON数据,data作为字典使用。
HttpRequest.scheme 代表请求的协议,http或者https
HttpRequest.path 一个字符串,代表所请求页面的完整路径,不带参数,不包括协议名或域名。例: "/music/bands/the_beatles/"
HttpRequest.method 一个字符串,代表请求中使用的HTTP方法。保证是大写的。
HttpRequest.COOKIES 包含所有cookie的字典。键和值是字符串。
HttpRequest.GET 包含所有给定HTTP GET参数的类字典对象
HttpRequest.POST 普通用法与GET类似,只是url不显示在浏览器地址栏。可以用带有空POST字典的POST发出请求(比如文件上传),因此应使用if r.POST:而不是if request.method == "POST":
HttpRequest.FILES 包含所有上载文件的类字典对象。是通过post方式发送的,但发送普通post请求时,r.FILES是空白的。关于文件,详见下一节
HttpRequest.META 包含所有可用HTTP标头的字典[2]。常用:r.META['HTTP_HOST'] -客户端发送的HTTP Host标头,网站的域名或IP;r.META['REMOTE_ADDR'] -客户端的IP地址。
HttpRequest.headers 不区分大小写,也不区分横线下划线,类似于dict的对象,该对象提供对请求中所有HTTP前缀的标头(plus Content-Length和Content-Type)的访问。包含浏览器和设备信息request.headers['User-Agent']:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)
方法 功能
HttpRequest.get_host() 返回请求的原始主机,获取客户端请求的服务器地址。类似于r.META['HTTP_HOST']
HttpRequest.is_ajax() 通过检查字符串的标头,判断是否通过XMLHttpRequest发送请求

GET

Django的理念不喜欢在地址栏中写很长很复杂的url:[3]

在你上网的过程中,很可能看见过像这样美丽的 URL: ME2/Sites/dirmod.asp?sid=&type=gen&mod=Core+Pages&gid=A6CD4967199A42D9B65B1B 。别担心,Django 里的 URL 规则 要比这优雅的多!

所以GET也只用来做一些简单的工作(翻页等),而不做会让数据库发生改变的功能。但是为了方便举例,这里有一个直观的修改数据库的代码片段,POST的用法类似:

def daka(request):
    id = -1
    if request.method == 'GET':
        rg = request.GET
        cs = ClkSign(
            nikeName=rg['nikeName'],
            name=rg['name'],
            userId=rg['userId'],
            locaAdd=rg['locaAdd'],
            locatude=rg['locatude'],
            dev_locatude=rg['dev_locatude'],
            datetime=timezone.now()
        )
        cs.save()
        id = cs.id
        return JsonResponse({'code': 1, '_id': id})

GET请求只包含字符串信息。通过request.method == 'GET'来判断是GET请求后,用request.GET就能获取携带信息的QueryDict,用法与字典类似。
并且,GET有长度限制,不同浏览器会有不同,但最多也只有8KB。而POST信息的长度限制是2GB,一般情况下足以满足需要。[4]

POST

POST的使用与GET很相似,但POST可以发送大文件,并且为了方式跨域,需要考虑csrf。

csrf

django为了安全起见,默认使用csrf,本服务器自身提供的网页只有写明csrf才能发送POST请求:[5]

1、不推荐禁用掉django中的CSRF。
2、我们可以再html页面的form表单中添加csrf_token,带着表单的请求一起发送到服务器去验证>

<form  enctype="multipart/form-data" method="post" action="{% url 'new_article' %}">
   {% csrf_token %}

3、在后端一定要使用render()的方法返回数据。

return render(request, 'article_new.html', {'article_list': article_list})
```  

其他网站的网页或者微信小程序若想向Django请求POST,在setting中要注释掉应用列表中的中间件django.middleware.csrf.CsrfViewMiddleware

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

这样DJango就不再做csrf验证了。

Ajax

request.body

处理前端用Ajax发来的json对象,存为一个字典,典型用法如下所示:

import json
def detail(r):
   data = json.loads(r.body)
   id = data['id']

JsonResponse[6]

典型用法如下所示:

>>> from django.http import JsonResponse
>>> response = JsonResponse({'foo': 'bar'})
>>> response.content
b'{"foo": "bar"}'
>>>return response

如果序列化非字典对象,您必须将safe 参数设置为False

>>> return JsonResponse([1, 2, 3], safe=False)

如果不写safe=False,会报错。这个safe主要是为了照顾老版本浏览器的兼容性。

HttpResponse

如果只需发送一个字符串类型的值,也不需要键名,使用HttpResponse更简单。

from django.http import HttpResponse
# ...
return HttpResponse('success')

  1. QueryDict对象

  2. HttpRequest.META

  3. (https://docs.djangoproject.com/zh-hans/3.0/intro/tutorial03/#overview)

  4. 简书-get请求的长度限制

  5. (https://www.cnblogs.com/chenchao1990/p/5339779.html)

  6. JsonResponse对象

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。