前后台分离开发
1.前台页面运行在前台服务器上,负责页面的渲染(静态文件的加载)与跳转
2.后台代码运行在后台服务器上,负责数据的处理(提供数据请求的接口)
跨域
什么是跨域?
通常情况下,A网页访问B服务器时,不满足以下三个条件中,其中之一就是跨域访问:
1.协议不同;
2.端口不同;
3.主机不同
如何解决?
#安装django-cors-headers模块 #在settings.py中配置 #注册app INSTALLED_APPS = [ 'corsheaders' ] #添加中间件 MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware' ] #允许跨域源 CORS_ORIGIN_ALLOW_ALL = True
''' 前台代码 $.ajax({ url: 'http://127.0.0.1:8731/login/', type: 'post', data: { usr: 'abc', pwd: '123' }, success: function (data) { console.log(data); // 可以完成页面的局部刷新 } }) 后台代码 def login(request): # 假设数据库存放的用户信息为 abc:123 if request.method == 'POST': usr = request.POST.get('usr', None) pwd = request.POST.get('pwd', None) if usr == 'abc' and pwd == '123': return JsonResponse({'status': 'OK', 'usr': usr}) return JsonResponse({'status': 'error', 'usr': None}) '''
文件上传
浏览器:
<form> <input class="file" type="file"> <button type="button" class="upload">上传</button> </form> <script> $('.upload').click(function () { var form_data = new FormData(); var file = $('.file')[0].files[0]; form_data.append('file', file); $.ajax({ url: '跨域上传地址', type: 'post', data: form_data, contentType: false, // 不设置内容类型 processData: false, // 不预处理数据 success: function (data) { console.log(data) } }) }) </script>
后台:
def upload(request): file = request.FILES.get('file', None) if file: with open(file.name, 'wb') as f: for line in file: f.write(line) return JsonResponse({ 'status': 'OK', 'msg': 'upload success' })
文件下载
浏览器:
<a href="http://127.0.0.1:8121/download/">下载</a> <button type="button" class="download">下载</button> <script> $('.download').click(function () { location.href = 'http://127.0.0.1:8121/download/' }) </script>
后台:
def download(request): file = open('123.zip', 'rb') response = FileResponse(file) response['Content-Type'] = 'application/octet-stream' response['Content-Disposition'] = 'attachment;filename="%s"' % file.name return response
Cookie
1.什么是cookie?
cookie指的是前端浏览器以明文的形式存放具有key、value信息特征的字符串。
2.cookie的作用
在前后台均可以访问并设置cookie,从而解决http协议的无状态特点所导致的前后两次请求无逻辑可循的问题(例如:不同用户登录后,再进入个人主页,明显是有信息区别的)
3.cookie简介
随着浏览器的发展,很多浏览器不再对cookie的个数加以限制,但是仍存在大小的限制,一般为4k;但是为了达到传输的高效,服务器的解析速度,还是建议开发者严格控制cookie的个数。
cookie初始:为页面文档document的一个字符串属性:document.cookie = 'key=value;'
Cookie的使用及其参数:
#Django用HttpResponse对象操作Cookie response = HttpResponse('所有的响应都是HttpResponse对象') #设置cookie:key,value与过期时间(max_age) response.set_cookie(key,value,max_age) #删除cookie:key response.delete_cookie(key) #设置加盐cookie:key,value与盐字符串(就是简易的加密) response.set_signed_cookie(key,value,salt) #通过request对象获取cookie # 获取key对应的value request.COOKIES.get(key, None) # 获取加盐后的key对应的value request.get_signed_cookie(key, salt) #set_cookie方法的其他参数 1. expires:过期时间,格式为字符串类型的时间 2. path:作用路径,/代表所有路径下均起作用 3. domain:作用域名 4. secure:布尔类型,浏览器是否通过HTTPS方式回传cookie 5. httponly:布尔类型,JS能否直接访问该条cookie
# views.py from django.shortcuts import render, redirect, HttpResponse # 确认登录装饰器 def login_check(func): def inner(request, *args, **kwargs): is_login = request.COOKIES.get('is_login', False) # 确定当前被装饰的请求,登录完毕可以跳转回去 url = request.get_full_path() if is_login: return func(request, *args, **kwargs) else: # 将回跳的路径作为参数(登录的表单action需要空着不写) return redirect('/login/?back_url=%s' % url) return inner # 主页 def index(request): return render(request, 'index.html') # 登录页面 def login(request): if request.method == "GET": return render(request, 'login.html') if request.method == "POST": # 获取回跳的地址 back_url = request.GET.get('back_url', '/index/') usr = request.POST.get('usr', None) pwd = request.POST.get('pwd', None) if usr == 'abc' and pwd == '123': # 确定回跳 response = redirect(back_url) # 登录成功获取cookie for i in range(500): response.set_cookie('usr%i' % i, usr) response.set_cookie('is_login', True) return response @login_check def order(request): print(request.COOKIES) usr = request.COOKIES.get('usr', None) return render(request, 'order.html', locals()) @login_check def user(request): usr = request.COOKIES.get('usr', None) return render(request, 'user.html', locals()) def logout(request): response = HttpResponse('注销成功') response.delete_cookie('is_login') response.delete_cookie('usr') return response
index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>主页</title> <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css"> </head> <body> <div class="container"> <div class="row"> <h1 class="page-header text-info text-center">主页</h1> </div> <div class="row"> <a href="/login/" class="btn text-danger"><h3>登录</h3></a> <a href="/user/" class="btn text-info"><h3>个人主页</h3></a> <a href="/order/" class="btn text-info"><h3>订单详情</h3></a> <a href="/login_out/" class="btn text-info"><h3>注销</h3></a> </div> </div> </body> </html> login.html <html lang="en"> <head> <meta charset="UTF-8"> <title>登录</title> </head> <body> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登录界面</title> <link rel="stylesheet" href="/static/login.css"> </head> <body> <div class="box"> <h2>欢迎登录</h2> <form action="" method="post"> <div class="usr"> 用 户:<input type="text" name="usr" placeholder="请输入用户名"> </div> <div class="usr"> 密 码:<input type="password" name="pwd" placeholder="请输入密码"> </div> <div class="login"> <input type="submit" value="登录"> </div> </form> </div> </body> </html> </body> </html> user.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>个人主页</title> <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css"> </head> <body> <h1 class="text-primary col-md-6 page-header text-center">{{ usr }}的个人主页</h1> </body> </html> order.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>订单详情</title> <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.css"> </head> <body> <h1 class="page-header text-center text-primary col-md-6">{{ usr }}的订单详情</h1> </body> </html>
Session
1.什么是session?
session指的是在后台通常以密文的形式存放key,value形式的数据,一个会话存放为数据库的一条字段。
2.session的作用
必须结合cookie使用,解决了cookie的不安全性。
3.session简介:session时存放在服务器端的key-value形式的状态数据。
session使用及其参数:
#常用操作: #设置 request.session['key1'] = 'value1' request.session['key2'] = 'value2' #过程: #1.生成一个随机字符串,作为主键; #2.在django_session表中插入有三个字段的一条数据(一条数据对应一个浏览器会话) --session_key:主键-随机字符串 --session_data:该会话拥有的所有key-value形成的大字典的加密字符串 --expire_date:过期时间,默认14天 #3.往浏览器中写入一条cookie,sessionid=主键的随机字符串 #获取 request.session.get('key',None) #删除 request.session.delete() #只删除当前会话对应的一条记录 request.session.flush() #除了删除当前会话对应的一条记录外,还删除对应浏览器中的cookie #其他 request.session.session_key # 获取当前会话对应的session_key request.session.exists('session_key') # 判断某session_key是否存在 request.session.clear_expired() # 清空所有过期的Session
settings.py中的配置:
1. 数据库Session SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默认) 2. 缓存Session SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎 SESSION_CACHE_ALIAS = 'default' # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置 3. 文件Session SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎 SESSION_FILE_PATH = None # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() 4. 缓存+数据库 SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎 5. 加密Cookie Session SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 引擎 其他公用设置项: SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认) SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径(默认) SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名(默认) SESSION_COOKIE_SECURE = False # 是否Https传输cookie(默认) SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输(默认) SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)(默认) SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期(默认) SESSION_SAVE_EVERY_REQUEST = False # 是否每次请求都保存Session,默认修改之后才保存(默认)