ajax 特点
- 局部刷新
- 异步请求
Django 中 ajax 的写法
ajax 是封装在 jQuery 中的,要使用 ajax,首先要引入 jQuery。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| {% load static %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body>
<h1>登录页面</h1> {#<form action="" method="post">#} {# {% csrf_token %}#} {# 用户名: <input type="text" name="username">#} {# 密码: <input type="text" name="password">#} {# <input type="submit">#} {#</form>#}
{% csrf_token %} <hr> 用户名: <input type="text" id="uname"> 密码: <input type="password" id="pwd"> <button id="sub">提交</button> <span id="error" style="color:red;font-size: 12px;"></span> </body>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script> {#<script src="{% static 'js/xx.js' %}"></script>#} <script> $('#sub').click(function () {
var uname = $('#uname').val(); var pwd = $('#pwd').val(); var csrf_token = $('[name="csrfmiddlewaretoken"]').val();
$.ajax({ url: '{% url "login" %}', type: 'post', data: {'uname': uname, 'pwd': pwd, 'csrfmiddlewaretoken': csrf_token}, success: function (res) { console.log('>>>>', res); if (res !== 'ok') { $('#error').text('用户名或者密码有误!') }else { location.href='/home/'; } } }) }) </script> </html>
|
CSRF 简介
CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。攻击者通过 HTTP 请求将数据传送到服务器,从而盗取回话的 cookie。盗取回话 cookie 之后,攻击者不仅可以获取用户的信息,还可以修改该 cookie 关联的账户信息。
所以解决 CSRF 攻击的最直接的办法就是生成一个随机的 csrftoken 值,保存在用户的页面上,每次请求都带着这个值过来完成校验。
ajax 通过认证
通过找到 csrf 逻辑经过模板渲染后生成的 input 标签,获取到 csrf token 的值。
hmtl 代码
ajax 可以直接提交数据,所以不需要将 input 标签包裹在 form 标签之中。
1 2 3 4
| {% csrf_token %} 用户名: <input type="text" id="uname"> 密码: <input type="password" id="pwd"> <button id="sub">提交</button>
|
js 代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| $('#sub').click(function () {
var uname = $('#uname').val(); var pwd = $('#pwd').val(); var csrf_token = $('[name="csrfmiddlewaretoken"]').val();
$.ajax({ url: '{% url "login" %}', type: 'post', data: {'uname': uname, 'pwd': pwd, 'csrfmiddlewaretoken': csrf_token}, success:function (res) { console.log('>>>>',res); if (res !== 'ok'){ $('#error').text('用户名或者密码有误!')
}else { location.href='/home/'; } } }) })
|
方式 2 模板渲染直接获取
data 数据部分的 csrf_token 认证的键值对的值直接写
经过模板渲染之后,它直接就是那个 input 标签的 value 值。
html 代码
同样,不需要将 input 标签包裹在 form 标签中。
1 2 3
| 用户名: <input type="text" id="uname"> 密码: <input type="password" id="pwd"> <button id="sub">提交</button>
|
js 代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| $('#sub').click(function () {
var uname = $('#uname').val(); var pwd = $('#pwd').val();
$.ajax({ url: '{% url "login" %}', type: 'post', data: {'uname':uname,'pwd':pwd,'csrfmiddlewaretoken':'{{ csrf_token }}'}, success: function (res) { console.log('>>>>',res); if (res !== 'ok'){ $('#error').text('用户名或者密码有误!') }else { location.href='/home/'; } } }) })
|
方式 3 通过 Cookie 获取
jQuery 中没有封装操作 Cookie 的代码,需要我们先引入。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <script src="{% static 'jquery.js' %}"></script> <script src="{% static 'jquery.cookie.js' %}"></script> <script> $('#btn').click(function () {
var uname = $('[type="text"]').val(); var pwd = $('[type="password"]').val();
$.ajax({ url: '/login/', type: 'post', headers: {'X-CSRFToken': $.cookie('csrftoken')}, data: {uname: uname, pwd: pwd}, success: function (res) { console.log(res); } }) }) </script>
|