一、请求
1.flask中,利用HTTP协议想服务器传参的几种途径
1.1 提取URL的特定部分,可以在服务器端的路由中用正则表达式截取:
如:/weather/2018
//前端发送请求:
$.ajax({
url:'http://www.baidu.com/weather/2018',
type:'get',
dataType:'json'
})
.done(function(data){
console.log(data)
})
.fail(function(error){
console.log(error)
})
# flask后盾接受数据:
# 使用正则转换器
@app.route("/weather/<re:userid>")
def index(userid):
return "%s" % userid
1.2 查询字符串(query string):
形如key1=value1&key2=value2;
// 前端发送请求
$.ajax({
url:"http://www.baidu.com/?key1=value1&key2=val2",
type:"get",
dataType:"json",
})
.done(function(data){
console.log(data)
})
# flask后端获取查询字符串的方式:
@app.route("/", methods=["GET","POST"])
def index():
val1 = request.args.get("key1")
return "%s" % val1
1.3 请求体(body)中发送的数据,比如表单数据,json,xml。
1.4 在http报文的头(header)中。
2. URL路径参数:
在定义路由URL时,可以使用正则表达式提取参数的方法从URL中获取请求参数,Django会将提取的参数直接传递到视图的参数中
2.1未命名参数按照定义顺序传递:
# urls.py
url(r"weather/([a-z]+)/(\d{4})/$", views.weather),
# views.py
def weather(request, city, year):
print("city=%s" % city)
print("year=%s" % year)
return HttpResponse("weather function")
终端:
2.2 命名参数传递:
# 在urls的路由规则中定义参数名
# urls.py
url(r"/weather/(?P<city>[a-z]+)/(?P<year>\d{4})/$", views.weather),
# views.py
def weather(request, city, year):
print("city=%s" % city)
print("year=%s" % year)
return HttpResponse("ok)
终端:
3.Django中的QueryDict对象:
3.1 QD的基本概念:
django中有一个QueryDict对象;
这个对象一般用来存储浏览器传递的参数;
一般默认的看成一个字典,但是他和一般的字典的不同之处在于:
- QueryDict这个字典可以用来处理一键多值的情况.
- QueryDict这个字典支持get()方法的使用
-
- 如果是一键一值:
QueryDict.get(key):获得的就是当前key对应的value;
- 如果是一键一值:
-
- 如果是一键多值:
QueryDict.get(key):获得的就是key对应的最后一个值
– 获取一键多值的方法:
QueryDict.getlist(key):获取这个键对应的所有值
- 如果是一键多值:
代码实例:
- get():
根据键获取值;
如果一个键同时拥有多个值将获取最后一个值;
如果键不存在则返回None值,可以设置默认值进行后续的处理;
# 默认值一般是default,可以省略
QueryDict.get('键',默认值)
# 或者:
QueryDict['键']
- gitlist():
根据键获取值,值以列表返回,可以获取指定键的所有值
如果键不存在则返回空列表[],可以设置默认值进行后续的处理
QueryDict.getlist('键',[默认值])
4.查询字符串(QueryString):
什么是查询字符串:
简单理解:就是请求地址中的参数部分,统称为:查询字符串(QueryString)
获取请求路径的查询字符串参数,可以通过request.GET属性获取,这个方法返回QueryDict对象
代码实例:
// 前端发送请求:
$.ajax({
url:'http://127.0.0.1:8000/reqresp/qs/?a=1&b=2&a=3',
type:'get',
dataType:'json'
})
.done(function(data){
console.log(data)
})
# django部分接受发送的参数并打印
# 视图函数
def qs(request):
a = request.GET.get('a')
b = request.GET.get('b')
alist = request.GET.getlist('a')
print(a) # 3
print(b) # 2
print(alist) # ['1', '3']
return HttpResponse("OK")
终端:
重要:
查询字符串不区分请求方式,即假使客户端进行POST方式请求,依然可以通过request.GET获取请求中的查询字符串数据.
注意:
- 这里的request.GET指的不是发送ajax用的get方法,而是指从url的查询字符串中获取的参数;
- 同理:request.POST指的不是ajax用的post方法,而是我们从请求体中获取的参数;
- 通过以上说明就明白:GET和POST这里指的都是获取参数的位置,而不是get、post请求
5.请求体:
请求体数据格式不固定,可以是表单类型字符串,可以是JSON字符串,可以是XML字符串,应区别对待。
可以发送请求体数据的请求方式有 POST、PUT、PATCH、DELETE。
Django默认开启了CSRF防护,会对上述请求方式进行CSRF防护验证,在测试时可以关闭CSRF防护机制,方法为在settings.py文件中注释掉CSRF中间件,如:
注释掉后,才能进行下面的验证.
5.1 表单类型(Form Data):
前端发送的表单类型的请求体数据,可以通过request.POST属性获取,返回QueryDict对象
代码实例:
# 视图函数
def get_body(request):
a = request.POST.get('a')
b = request.POST.get('b')
alist = request.POST.getlist('a')
print(a)
print(b)
print(alist)
return HttpResponse("OK")
postman截图:
注意:
- 如果是表单数据,发送的请求不但要求body中是表单的键值对,也要求请求头中content-type的类型是application/x-www-form-urlencoded.如果请求中的不是这样写的类型,上面的request.POST.get()方法也不可以使用
- 使用request.POST.get()方法需要满足一下条件:
5.2非表单类型(Non-Form Data)
非表单类型的请求体数据,Django无法自动解析
可以通过request.body属性获取最原始的请求体数据,自己按照请求体格式(JSON、XML等)进行解析。
其中: request.body返回bytes类型。
代码实例:
要获取请求体中的如下json数据:
{“a”:1, “b”:2}
视图函数代码:
import json # 引用的是python内置的json模块,用于json格式的转化
def get_body_json(request):
json_bytes = request.body
json_str = json_bytes.decode()
#python3.6及以上版本中, json.loads()方法可以接收str和bytes类型
#但是python3.5以及以下版本中, json.loads()方法只能接收str, 所以我们的版本如果是
#3.5 需要有上面的编码步骤.
req_data = json.loads(json_str)
print(req_data['a'])
print(req_data['b'])
return HttpResponse("OK")
功能效果:
6.请求头:
我们可以铜鼓request.META属性获取请求头headers中的数据;
request.META为字典类型
常见的请求头:
POST /reqresp/req/ HTTP/1.1
Host: 127.0.0.1:8000
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
Postman-Token: dd531a45-7518-1e8f-63a5-be03ed593471
a=1&b=2&a=3
通过request.META获取的时候,需要使用如下所示的用法:
参数 | 说明 | 解释 |
---|---|---|
CONTENT_LENGTH | The length of the request body (as a string). | 请求体的长度(作为字符串) |
CONTENT_TYPE | The MIME type of the request body. | 请求主体的MIME类型 |
HTTP_ACCEPT | Acceptable content types for the response. | 响应的可接受内容类型。 |
HTTP_ACCEPT_ENCODING | Acceptable encodings for the response. | 响应的可接受编码 |
HTTP_ACCEPT_LANGUAGE | Acceptable languages for the response. | 响应的可接受语言。 |
HTTP_HOST | The HTTP Host header sent by the client. | 客户端发送的HTTP主机头。 |
HTTP_REFERER | The referring page, if any. | 参考页,如果有的话。 |
HTTP_USER_AGENT | The client’s user-agent string | |
QUERY_STRING | The query string, as a single (unparsed) string. | 客户端的用户代理字符串 |
REMOTE_ADDR | The IP address of the client. | 客户端的IP地址 |
REMOTE_HOST | The hostname of the client. | 客户端的主机名 |
REMOTE_USER | The user authenticated by the Web server, if any. | 用户通过Web服务器进行认证,如果有的话 |
REQUEST_METHOD | A string such as “GET” or “POST”. | 请求方法,如“GET”或“POST”。 |
SERVER_NAME | The hostname of the server. | 服务器的主机名 |
SERVER_PORT | The port of the server (as a string). | 服务器的端口(作为字符串) |
具体使用:
def get_headers(request):
# 获取请求头的数据类型
value = request.META["CONTENT_TYPE"]
print(value)
return HttpResponse("OK")
实现效果:
7. 其他常用HttpRequest对象属性:
- method: 一个字符串,表示请求使用的HTTP方法,常用值包括:‘GET’, ‘POST’.
- user: 请求的用户对象.
- path:一个字符串,表示请求的页面的完整路径,不包含域名和参数部分.
- encoding:一个字符串,表示提交的数据的编码方式
-
- 如果为None则表示使用浏览器的默认设置,一般为utf-8.
-
- 这个属性时可写的,可以通过修改它来修改访问表单数据使用的编码,接下来对属性的任何访问将使用新的encoding.
- FILES: 一个类似于字典的对象,包含所有的上传文件
效果: