提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”。
即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML,现在更多使用json数据)。
AJAX 不是新的编程语言,而是一种使用现有标准的新方法。
AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
(这一特点给用户的感受是在不知不觉中完成请求和响应过程)
AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。
a.同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
b.异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。
AJAX除了异步的特点外,还有一个就是:浏览器页面局部刷新;(这一特点给用户的感受是在不知不觉中完成请求和响应过程)
views.py
def login(request):
if request.method == 'GET':
return render(request, 'login.html')
else:
data = request.POST
print(data) #
username = data.get('xname')
password = data.get('pwd')
if username == 'yuantao' and password == '666':
return HttpResponse('ok') # 200
# ret = render(request, 'login.html', {'error':'用户名或者密码有误!!', 'username':username,'password':password})
ret = HttpResponse('not ok')
ret.status_code = 400 # 设置状态码
return ret
def index(request):
# import json
userinfo = {
'name':'春培',
'age': 18,
}
# userinfo_st = json.dumps(userinfo, ensure_ascii=False)
# return HttpResponse('ok')
# ret = HttpResponse(userinfo_st)
# ret['content_type'] = 'application\json'
# return HttpResponse(userinfo_st,content_type='application\json')
return JsonResponse(userinfo)
def food(request):
# import json
#
# food_list = ['黄瓜', '茄子', '香蕉', '萝卜', '冬瓜']
# food_str = json.dumps(food_list)
#
# return HttpResponse(food_str)
def food(request):
# import json
# food_list = ['黄瓜', '茄子', '香蕉', '萝卜', '冬瓜']
food_list = ['黄瓜', '茄子', '香蕉', '萝卜', '冬瓜']
# food_str = json.dumps(food_list)
# 响应非字典类型数据时,需要加上safe=False的参数
return JsonResponse(food_list, safe=False)
login.html
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<meta name="viewport" content="width=device-width, initial-scale=1">
head>
<body>
{#<iframe src="http://www.baidu.com" frameborder="0" style="width: 100%;height: 500px">iframe>#}
<h1>32期皇家会所会员ajax登录页面h1>
用户名: <input type="text" id="username">
密码: <input type="password" id="password">
<button id="btn">ajax提交button>
<h1 id="ajax_error" style="color:Red;">h1>
<h1 id="msg">h1>
<ul id="food_ul">
ul>
body>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js">script>
<script>
// 当后台响应的响应头键值对中 包含: content-type:application\json
// ajax接受到本次响应之后,会查看响应头键值对中有没有content-type,如果有,并且值为application\json,那么
// ajax就知道,本次响应回来的数据,就是json数据,那么ajax会直接对响应数据进行反序列化,然后再交给success对应的
// 回调函数作为参数
$.ajax({
url:'/index/',
type:'get',
success:function (res){
console.log('>>>>>>>>>>>>>>>>',res,typeof res);
$('#msg').text(res.name);
{#var userinfo = JSON.parse(res);#}
{#console.log('>>>>>>>>>>>>>>>>',userinfo,typeof userinfo);#}
{#$('#msg').text(userinfo.name)#}
},
});
$.ajax({
url:'/food/',
type:'get',
success:function (res){
console.log('>>>>>>>>>>>>>>>>',res,typeof res);
{#var food_list = JSON.parse(res);#}
{#console.log('>>>>>>>>>>>>>>>>',food_list,typeof food_list);#}
var ulEle = $('#food_ul');
// 创建li标签
{#$.each(food_list,function (k,v){#}
$.each(res,function (k,v){
// k是列表的索引
// v是列表的元素
// 给li标签添加文本内容
var newLiEle = document.createElement('li');
newLiEle.innerText = v;
// 将li标签添加到ul标签中
ulEle.append(newLiEle);
})
},
});
$('#btn').click(function (){
var uname = $("#username").val();
var password = $("#password").val();
$.ajax({
type:'post', // 请求方法.
url:'/login/',
// 如果不携带数据,可以不写data属性
data:{xname:uname, pwd:password}, // xname:chao,pwd:123 request.POST.get('xname')
success:function (res){ // res接受的是请求成功之后的响应结果,如果ajax判断请求成功和失败,有后台决定
// 后台响应的状态码如果是2xx\3xx等,ajax发现应用状态为2xx\3xx等,ajax就知道请求成功了
// ajax会自动触发success对应的回调函数,并且将接受到的响应传值给了函数
console.log('success',res);
},
error:function (error){ //后台响应的状态码为4xx或者5xx表示请求失败或者服务器出问题了,没有正常响应本次请求的内容
console.log('error>>>>>',error); // ajax接受到响应,如果发现响应状态码为4xx或者5xx,那么ajax会自动触发error对应的函数,并将
// 响应结果传给函数作为参数(error参数)
{#$('#ajax_error').text('输入的用户名或者密码有误!');#}
$('#ajax_error').text(error.responseText);
}
})
})
script>
html>
1.无连接
将协议设计为请求时建连接、请求完释放连接,以尽快将资源释放出来服务其他客户端。
2.无状态
什么是无状态?
无状态的意思是每次请求都是独立的,
它的执行情况和结果与前面的请求和之后的请求都无直接关系,
它不会受前面的请求响应情况直接影响,
也不会直接影响后面的请求响应情况
简单的来说:无状态是指服务器不知道客户端是什么状态。
对于无状态的解释:
要明白,这句话的含义是指在说明,http协议作为技术背景的web应用程序请求——应答模式是无状态的,这个事实基本不会发生改变,
也不会因为加入cookies、session机制而变成有状态的。
要明白,这种前后因果关系:“我们要实现的是一种web应用,实现这种应用的协议我们选择了http这种本质上是无状态的通信协议。
但是事实上,我们需要我们的web应用是有状态的。所以我们加入了cookies、session等机制去实现有状态的web应用。
因为http无状态,所以出现了cookie,cookie是一种浏览器技术
1.浏览器访问服务端,带着一个空的cookie,
2.然后由服务器产生内容,浏览器收到相应后保存在本地;
3.当浏览器再次访问时,浏览器会自动带上Cookie,这样服务器就能通过Cookie的内容来判断这个是“谁”了。
Cookie大小上限为4KB;
一个服务器最多在客户端浏览器上保存20个Cookie;
一个浏览器最多保存300个Cookie,因为一个浏览器可以访问多个服务器。
上面的数据只是HTTP的Cookie规范,但在浏览器大战的今天,一些浏览器为了打败对手,
为了展现自己的能力起见,可能对Cookie规范“扩展”了一些,例如每个Cookie的大小为8KB,最多可保存500个Cookie等!
但也不会出现把你硬盘占满的可能!
注意,不同浏览器之间是不共享Cookie的。也就是说在你使用IE访问服务器时,
服务器会把Cookie发给IE,然后由IE保存起来,当你在使用FireFox访问服务器时,不可能把IE保存的Cookie发送给服务器。
Cookie是通过HTTP请求和响应头在客户端和服务器端传递的:
Cookie:请求头,客户端发送给服务器端;
格式:Cookie: a=A; b=B; c=C。即多个Cookie用分号离开;
Set-Cookie:响应头,服务器端发送给客户端;
格式:一个Cookie对象一个Set-Cookie: Set-Cookie: a=A Set-Cookie: b=B Set-Cookie: c=C
如果服务器端发送重复的Cookie那么会覆盖原有的Cookie,例如客户端的第一个请求服务器端发送的Cookie是:Set-Cookie: a=A;
第二请求服务器端发送的是:Set-Cookie: a=AA,那么客户端只留下一个Cookie,即:a=AA。
def login(request):
if request.method == 'GET':
return render(request, 'login.html')
else:
username = request.POST.get('username')
password = request.POST.get('password')
if username == 'root' and password == '123': #登录验证
ret = redirect('home')
ret.set_cookie('is_login', 'xxx') #设置cookie,如果有同名(键)的cookie,那么就是修改cookie
ret.set_cookie('username', username)
return ret
return redirect('login')
def home(request):
# ret = render(request, 'home.html')
# ret.set_cookie('is_login', True) #键相同,就是修改cookie
print('>>>>', request.COOKIES) #{'is_login': 'True', 'username': 'root'} 字典数据
status = request.COOKIES.get('is_login') # 获取请求携带的cookie数据
print(status, type(status))
if status == 'xxx':
return render(request, 'home.html')
else:
return redirect('login')
def cart(request):
print('>>>>',request.COOKIES) #{is_login:true, username:root}
status = request.COOKIES.get('is_login') # 获取请求携带的cookie数据
print(status, type(status))
if status == 'xxx':
cart_list = ['女朋友1', '欧美女朋友',]
return render(request, 'cart.html',{'cart_list':cart_list})
else:
return redirect('login')
# 删除cookie
def logout(request):
ret = redirect('login')
ret.delete_cookie('is_login')
return ret
Cookie是明文存储的,而Session是加密的
Cookie虽然在一定程度上解决了“保持状态”的需求,但是由于Cookie本身最大支持4096字节,以及Cookie本身保存在客户端,可
能被拦截或窃取,因此就需要有一种新的东西,它能支持更多的字节,并且他保存在服务器,有较高的安全性。这就是Session。
Cookie弥补了HTTP无状态的不足,让服务器知道来的人是“谁”;
但是Cookie以文本的形式保存在本地,自身安全性较差;
所以我们就通过Cookie识别不同的用户,对应的在Session里保存私密的信息以及超过4096字节的文本。
# 设置session
request.session['k1'] = 123
request.session.setdefault('k1',123)
# 获取session
request.session['k1']
request.session.get('k1',None)
# 删除session
del request.session['k1']
# 清空session
request.session.flush()
这是一段登录的视图函数,在函数中添加两个session,在添加session时,做了三件事
def login(request):
if request.method == 'GET':
return render(request, 'login.html')
else:
username = request.POST.get('username')
password = request.POST.get('password')
if username == 'root' and password == '123': #登录验证
request.session['is_login'] = True #
request.session['username'] = username
request.session.set_expiry(5) # 设置连接时间为5秒
'''
1 生成随机字符串
2 加入到cookie中,{sessioid: 'asdfasdfasdf'}
3 将设置的session数据(is_login,username...),序列化然后加密保存到数据库中.
django-session表
'''
return redirect('home')
return redirect('login')
def home(request):
status = request.session.get('is_login') # 获取请求携带的cookie数据
'''
1 取出cookie中的sessionid对应的随机字符串
2 通过随机字符串去django-session表中找到对应记录
3 将记录中session_data的数据进行解密并反序列化,然后取出键对应的值
'''
if status == True:
return render(request, 'home.html')
else:
return redirect('login')
# 0.session你需要注意的点
'''
注意:1.session数据是保存在服务端的(存在?),给客户端返回的是一个随机字符串
然后给这个随机字符串配一个固定的键 这个键叫做sessionid,也就是说sessionid存储的就是随机字符串
2.在默认情况下操作session的时候需要django的默认一张django_session表
django_session表中存放着三个字段:session_key session_data expire_data
3.django默认session的过期时间是14天,但是你也可以人为的修改它
4.django_session表中的数据条数是取决于浏览器的
同一个计算机上同一个浏览器只会有一条数据。
如果是不同的浏览器,就会有多条数据
但是当session过期的时候可能会出现多条数据对应一个浏览器,但是这种现象不会持续很久,django内部会自动识别过期的数据清除,你也可以通过代码去清除
5.session是保存在服务端的,但是session的保存位置可以有多种选择
1.可以存在自己的mysql数据库中
2.可以存在文件里面
3.可以存在缓存中:redis,memcache
'''
# 1.django中的session操作 【设置 获取 修改 删除】
'''
1.设置session
request.session['key'] = value
2.获取session
request.session.get('key')
3.设置session过期时间
request.session.set_expiry()
括号内可以放四种类型参数
1.整数:多少秒
2.日期对象:Datetime 到了指定日期就失效
3.0:一旦当前浏览器窗口关闭 立刻失效
4.什么都不写:失效时间就取决于django内部全局session默认的失效时间(14天)
4.清除session
request.session.delete() : 只删服务端的 客户端的不删
request.session.flush() :浏览器和服务端都清空[常用]
5.像设置字符串和获取字符串,是可以做一个加盐(加密)处理的,不是很重要就不细说了....
5.session还有很多属性,在这就不再一一介绍了
'''
# 2.知道这些了,我们先来搞一个session操作
'''
1.配置一个url,叫做set/session,并且定义视图函数set_session
2.def set_session(request):
request.session['hobby']='girl'
return HttpResponse('ok')
3.运行django项目 然后去django_session表中查看 会发现django_session表中多了一条数据
4.现在设置session没有问题了,那么如何获取session呢?
5.再配置一个url,叫做get/session,并且定义视图函数get_session
def get_session(request):
print(request.session.get('hobby'))
return HttpResponse('ok')
6.运行django项目 进入get/session路径 可以打印出girl,girl就是session键对应的值
7.现在设置session和获取session都已经成功了,接下来分析设置session和获取session内部究竟做了什么事
request.session['hobby']='girl'
1.django内部会自动帮你生成一个随机字符串
2.django内部自动将随机字符串和对应的数据存储在django-session表中
1.先在内存中产生操作数据的缓存
2.在响应经过django中间件的时候才真正的操作数据库
3.将产生的随机字符串返回给客户端浏览器保存
request.session.get('hobby')
1.自动从浏览器请求中获取sessionid对应的随机字符串
2.拿着该随机字符串去django-session表中查找对应的数据
3.进行比对
如果比对上了,则将对应的数据取出并以字典的形式封装到request.session中
如果比对不上,则request.session.get()返回的值是None
--------------------------------------------------------------------------------------
8.session除了设置和获取,也有一些额外的操作
1.session设置值可以设置多个的
request.session['hobby1']='girl1'
request.session['hobby2']='girl2'
request.session['hobby3']='girl3'
request.session['hobby4']='girl4'
那问题就来了,如果设置了四个session,在django_session表中是有一条数据还是多条数据呢?
在django_session表中,只有一条数据,但是你设置了四个session,你可以通过四个request.session.get(key)分别获取他们的value,四个是都可以打印出来的
为什么session只有一条数据呢?如果每存一次开辟一个新的数据,数据库表数据会难以承担,为了节省服务端资源
9.知道了如何删除session,那我们现在定义一个视图函数del_session
def del_session(request):
request.session.delete()
return HttpResponse('ok')
'''