Django——Ajax相关
Ajax简介
AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML,现在更多使用json数据)。
- 同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
- 异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。
AJAX除了异步的特点外,还有一个就是:浏览器页面局部刷新;(这一特点给用户的感受是在不知不觉中完成请求和响应过程)
AJAX应用场景
索引擎根据用户输入的关键字,自动提示检索关键字。
还有一个很重要的应用场景就是注册时候的用户名的查重。
其实这里就使用了AJAX技术!当文件框发生了输入变化时,使用AJAX技术向服务器发送一个请求,然后服务器会把查询到的结果响应给浏览器,最后再把后端返回的结果展示出来。
整个过程中页面没有刷新,只是刷新页面中的局部位置而已!
当请求发出后,浏览器还可以进行其他操作,无需等待服务器的响应!
整个过程中页面没有刷新,只是局部刷新了;
在请求发出后,浏览器不用等待服务器响应结果就可以进行其他操作;
AJAX的优缺点
优点:
- AJAX使用Javascript技术向服务器发送异步请求
- AJAX无须刷新整个页面
- 因为服务器响应内容不再是整个页面,而是页面中的部分内容,所以AJAX性能高;
缺点:
- 每个点击即请求一次,服务端的压力会增大。
知识储备:
需要的基础知识
HTML / XHTML
CSS
JavaScript / DOM
什么是JSON?
JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation)
JSON 是轻量级的文本数据交换格式
JSON 独立于语言 *
JSON 具有自我描述性,更易理解
* JSON 使用 JavaScript 语法来描述数据对象,但是 JSON 仍然独立于语言和平台。JSON 解析器和 JSON 库支持许多不同的编程语言。
stringify与parse方法:
JavaScript中关于JSON对象和字符串转换的两个方法:
JSON.parse(): 用于将一个 JSON 字符串转换为 JavaScript 对象
JSON.parse('{"name":"Q1mi"}');
JSON.parse('{name:"Q1mi"}') ; // 错误
JSON.parse('[18,undefined]') ; // 错误
JSON.stringify(): 用于将 JavaScript 值转换为 JSON 字符串。
JSON.stringify({"name":"Q1mi"})
Django项目中如何使用json:
首先前端需要一个正确的序列化后的数据
注意:contentType:"application/json"一旦设定,data必须是json字符串,不能是json对象
- contentType:默认值:"application/x-www-form-urlencoded"。发送信息至服务器时内容编码类型。用来指明当前请求的数据编码格式;urlencoded:?a=1&b=2;如果想以其他方式提交数据,比如contentType:"application/json",即向服务器发送一个json字符串;
前端代码:
$("#b1").click(function () {
console.log(dict);
json_obj = JSON.stringify({'dict':dict, 'data':$("#a1").attr("value")});
console.log(json_obj);
$.ajax({
url: "/index/",
type: "POST",
data: json_obj,
contentType:"application/json",
success: function (data) {
window.location.href = "/index/";
}
})
})
- 后端解析数据
-
request_json = json.loads(request.body)
jQuery实现的AJAX:
AJXA语法
- 一般请求
$.ajax({
url: "/index/", #往哪发送请求
type:"POST", #请求的方法
data:{name:"dream",age:18}, #请求数据
success:function(data){
#请求被正常响应时,自动执行的回调函数,data为返回值
}
})
- 提交携带文件类型的请求
var formData = new FormData(); #生成一个FormData
var =fileobj = $("#f1")[0].files[0]#得到一个用户选中的文件对象
formData.append("f1",fileobj) # 向formData对象中添加间值对数据
$.ajax({
url: "/index/", #往哪发送请求
type:"POST", #请求的方法
processData: false, #不让jQuery处理我的数据
contentType: false, #不让jQuery设置请求头
data:formData, #请求数据
success:function(data){
#请求被正常响应时,自动执行的回调函数,data为返回值
}
})
$.ajax参数
async
类型:Boolean
默认值: true。默认设置下,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为 false。
注意,同步请求将锁住浏览器,用户其它操作必须等待请求完成才可以执行。
data
类型:String
发送到服务器的数据。将自动转换为请求字符串格式。GET 请求中将附加在 URL 后。查看 processData 选项说明以禁止此自动转换。必须为 Key/Value 格式。如果为数组,jQuery 将自动为不同值对应同一个名称。如 {foo:["bar1", "bar2"]} 转换为 '&foo=bar1&foo=bar2'。
type
类型:String默认值: "GET")。请求方式 ("POST" 或 "GET"),
默认为 "GET"。注意:其它 HTTP 请求方法,如 PUT 和 DELETE 也可以使用,但仅部分浏览器支持。
url
类型:String
默认值: 当前页地址。发送请求的地址。
processData
类型:Boolean
默认值: true。默认情况下,通过data选项传递进来的数据,如果是一个对象(技术上讲只要不是字符串),都会处理转化成一个查询字符串,以配合默认内容类型 "application/x-www-form-urlencoded"。如果要发送 DOM 树信息或其它不希望转换的信息,请设置为 false。
- 注意:如果不需要jQuery去处理发送的数据是,请修改为false
contentType
类型:String
默认值: "application/x-www-form-urlencoded"。发送信息至服务器时内容编码类型。默认值适合大多数情况。如果你明确地传递了一个 content-type 给 $.ajax() 那么它必定会发送给服务器(即使没有数据要发送)。
- 注意:如果需要jQuery不去设置Content-Type请求头,则设置默认值为false。
success
类型:Function
请求成功后的回调函数。
参数:由服务器返回,并根据 dataType 参数进行处理后的数据;描述状态的字符串。
这是一个 Ajax 事件。
jQuery实现AJAX上传文件:
需要注意:不适用form表单提交数据时,需要在函数内使用 FormData() 方法生成一个表单对象
var formData = new FormData();
# 上传文件
def upload(request):
if request.method == 'POST':
file_obj = request.FILES.get('file',None)
if file_obj:
with open(file_obj.name,'wb') as f:
for chunk in file_obj.chunks():
f.write(chunk)
return HttpResponse("上传成功")
return render(request,'upload.html')
return render(request,'upload.html'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>上传文件</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
</head>
<body> <input id="i1" type="file">
<button id="b1">点我</button> <script src="/static/jquery-3.3.1.min.js"></script>
<script src="/static/setupAjax.js"></script>
<script>
$("#b1").click(function () {
// 生成表单对象
var formData = new FormData();
formData.append("file",$("#i1")[0].files[0]);
$.ajax({
url: "/upload/",
type: "POST",
// 告诉jQuery不要去处理发送的数据
processData: false,
// 告诉jQuery不要去设置Content-Type请求头
contentType: false,
data: formData,
success:function (data) {
console.log(data)
}
})
})
</script>
</body>
</html>
jQuery实现最基础监控注册用户是否注册
注意:尽量不要使用input事件,因为input事件是实时监听,会给服务器造成压力。
这里选用的是,失去焦点事件,blur
前端代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
<style>
.error {
color: red;
}
</style>
</head>
<body>
<div>
<label for="i1">用户名</label>
<input type="text" id="i1">
<span class="error" id="s1"></span>
</div>
<div>
<label for="p1">密码</label>
<input type="password" id="p1">
</div>
<div>
<button id="b1">提交注册</button>
</div> <script src="/static/jquery-3.3.1.min.js"></script>
<script>
// 监控用户名输入框的焦点,只要i1失去焦点,就要把用户填写的往后台发送
$("#i1").blur(function () {
// 将s1的初始值设为空
$("#s1").text("");
// 获取i1的值,即用户输入的值
var value = $(this).val();
// 调用ajax
$.ajax({
// 提交到什么地方
url: "/res2/",
// 以什么方式提交
type: "POST",
// 传送到后台的数据
data: {name: value},
// 回调函数,data为返回值
success: function (data) {
console.log(data);
if (data.no_ok) {
// 如果用户已存在
$("#s1").text(data.msg)
}
}
})
})
</script> </body>
</html>
后端代码:
def res2(request):
from django.http import JsonResponse
res = {"no_ok": 0}
if request.method == 'POST':
print(request.POST)
user_name = request.POST.get('name')
if user_name == 'dream':
res = {"no_ok": 1, "msg": "用户已存在."}
return JsonResponse(res)
return render(request,'res2.html')
JS实现AJAX:
<script>
let b1Ele = document.getElementById("b1");
b1Ele.onclick = function () {
// 1. 生成xmlHttp对象
let xmlHttp = new XMLHttpRequest();
// 2. 调用xmlHttp的open方法设置请求相关配置项
xmlHttp.open("POST", "/ajax_js/", true);
// 3. 设置请求头
xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// 4. 调用send方法发送数据
xmlHttp.send("username=dream&age=16");
// 5. 处理返回的响应
xmlHttp.onreadystatechange = function () {
if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
alert(xmlHttp.responseText);
}
};
}
</script>
AJAX请求如何设置csrf_token:
如果不设置csrf_token,则无法往后端发送数据,点击查看详细
方式一
通过获取返回的cookie中的字符串,放在请求头中发送。
注意:需要在html中引入jquery.cookie.js插件
- 导入<script src="/static/jquery.cookie.js"></script>
- 从Cookie取csrf_token,并设置ajax请求头
<script>
$("#b1").click(function () {
var name = $("#i1").val();
var pwd = $("#p1").val();
$.ajax({
url: "/register/",
type: "POST",
headers: {"X-CSRFToken": $.cookie('csrftoken')}, // 从Cookie取csrf_token,并设置ajax请求头
data: {name: name, pwd: pwd},
success:function (data) {
if (!data.code){
// 登陆成功
location.href = data.data;
}
}
})
})
</script>
方式二:
手动把csrf_token的值取到,塞进请求的data中
$("#b11").click(function () {
// 点击之后要做的事儿
$.ajax({
url: "/ajax_test2/",
type: "POST",
data: {
i11: $("#i11").val(),
i22: $("#i22").val(),
// 取到csrf_token的值
csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val()
},
success: function (data) {
console.log(data);
$("#i33").val(data);
}
})
});
方式三:
在一个单独的JS文件中,给$.ajax统一设置一下请求头
- 导入自己写的js文件 setupAjax.js
文件代码
复制保存到js文件中,导入到html中即可使用
/**
* Created by oldboy on 2018/6/27.
*/
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
注意事项:
- 如果发送的data中,数据不是简单的字符串或数字,需要用JSON.stringify()转换成JSON字符串
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>json提交数据</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
name<input type="text" id="n1">
password<input type="password" id="p1">
<button id="b1">提交</button>
<script src="/static/jquery-3.3.1.min.js"></script>
<script src="/static/setupAjax.js"></script>
<script>
$("#b1").click(function () {
$.ajax(
{
url:"login",
type:"POST",
// 告诉游览器我发送的是一个json数据
contentType:"application/json",
data:JSON.stringify({name:$("#n1").val(),pwd:$("#p1").val()}),
success:function (data) {
console.log(data)
}
}
)
}
)
</script>
</body>
</html>
反序列化
import json
json.loads(request.body)
在求头中设置编码格式:
- 常用的三种编码格式
application/x-www-form-urlencoded
json
formdata
- 告诉游览器我使用的是json编码格式
- 如果不设置则会采用默认的
Django——Ajax相关的更多相关文章
- Django ajax MYSQL Highcharts<1>
Another small project with django/Ajax/Mysql/Highcharts. 看下效果图 - delivery dashboard .嘿嘿 是不是还蛮好看的. 废 ...
- django ajax练习
这几天遇到了django ajax请求出错的问题,总结一下 前端js:我这里创建的是一个字典格式的数据,前端js收到字典之后也是要用字典的形式去解包后台传送过来的数据,比如我下面的写法:data['s ...
- 关于Django Ajax CSRF 认证
CSRF(Cross-site request forgery跨站请求伪造,也被称为“one click attack”或者session riding,通常缩写为CSRF或者XSRF,是一种对网站的 ...
- Django 模板相关
Django 模板相关 视图函数只是直接返回文本,而在实际生产环境中其实很少这样用,因为实际的页面大多是带有样式的HTML代码,这可以让浏览器渲染出非常漂亮的页面.目前市面上有非常多的模板系统,其中最 ...
- django ajax增 删 改 查
具于django ajax实现增 删 改 查功能 代码示例: 代码: urls.py from django.conf.urls import url from django.contrib impo ...
- python学习-- Django Ajax CSRF 认证
使用 jQuery 的 ajax 或者 post 之前 加入这个 js 代码:http://www.ziqiangxuetang.com/media/django/csrf.js /*======== ...
- AJAX 相关笔记
AJAX (Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)). 平时工作中使用ajax的频率挺高的,这里整理了一些ajax相关的小知识,后续 ...
- django AJAX 的应用
目录 AJAX 的使用 AJAX简介 AJAX常见应用情景 AJAX的优缺点 jQuery实现的AJAX JS实现AJAX AJAX请求如何设置csrf_token Form表单上传文件 AJAX上传 ...
- Django --- csrf相关,auth相关
目录 1.csrf相关 1.跨站请求伪造 2.跨站请求伪造问题解决 3.crsf中间件 4.csrf装饰FBV的装饰器 5.csrf装饰CBV的装饰器 6.django settings源码刨析 2. ...
随机推荐
- SNOI2017 礼物
题解 设前\(n\)个人的礼物个数和为\(F_n\), 那么显然\[F_n = 2 \times F_{n-1} + i^k\] 考虑矩阵快速幂 棘手的问题是:\(i^k\)不是可以直接用矩阵乘法可以 ...
- 记录ViewPager配合Fragment使用中遇到的一个问题
java.lang.IllegalStateException: FragmentManager is already executing transactions 如图所示: 当调用 notifyD ...
- @ContrllerAdvice全局异常
@ControllerAdvice,是Spring3.2提供的新注解,它是一个Controller增强器,可对controller中被 @RequestMapping注解的方法加一些逻辑处理.最常用的 ...
- java中 运算符
我们先讨论 &,&&,| ,|| 这四个运算符 boolean a=true; boolean b=true; boolean c=false; //输出:a为true,b ...
- php array_search()函数 语法
php array_search()函数 语法 作用:在数组中搜索某个键值,并返回对应的键名.dd马达生产厂家 语法:array_search(value,array,strict) 参数: 参数 描 ...
- BZOJ 2726: [SDOI2012]任务安排 斜率优化 + 凸壳二分 + 卡精
Code: #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) # ...
- 【CF1244D】Paint the Tree(树形DP,树)
题意: n<=1e5,1<=a[i][j]<=1e9 思路: 不是很懂INF为什么要开到1e15,我觉得只要1e14就好 #include<bits/stdc++.h> ...
- PHP Timer 页面运行时间监测类
转至:http://blog.csdn.net/fdipzone/article/details/20160567 php Timer 页面运行时间监测类,可按不同key监测不同的运行时间 Timer ...
- 20180708-Java变量类型
public class Test{ public void pupAge(){ int age = 0; age = age + 7; System.out.println("Puppy ...
- (最小割)Path
http://acm.hdu.edu.cn/showproblem.php?pid=6582 思路:找到最短路核心边建图,跑一遍最小割,最短路核心边的定义为设起点到每个点的最短距离为d[i],每个点到 ...