Django JSON,AJAX
JSON
概念
- JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation)
- JSON 是轻量级的文本数据交换格式
- JSON 独立于语言 *
- JSON 具有自我描述性,更易理解
示例
- ["one", "two", "three"]
- { "one": 1, "two": 2, "three": 3 }
- {"names": ["张三", "李四"] }
- [ { "name": "张三"}, {"name": "李四"} ]
格式不正确的示例
- { name: "张三", 'age': 32 } // 属性名必须使用双引号
- [32, 64, 128, 0xFFF] // 不能使用十六进制值
- { "name": "张三", "age": undefined } // 不能使用undefined
- { "name": "张三","birthday": new Date('Fri, 26 Aug 2011 07:13:10 GMT'),"getName": function() {return this.name;} // 不能使用函数和日期对象}
相关方法
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"})
和XML的比较
- 书写简单
- 一目了然
- 可以由解释引擎直接处理
- 无需另外添加解析代码
AJAX
概念
- 使用Javascript语言与服务器进行异步交互进行传输的数据的传输
- 在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
- 无需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。
- 同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
- 异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发第二个请求
示例
// HTML部分代码
!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>AJAX局部刷新实例</title>
</head>
<body> <input type="text" id="i1">+
<input type="text" id="i2">=
<input type="text" id="i3">
<input type="button" value="AJAX提交" id="b1"> <script src="/static/jquery-3.2.1.min.js"></script>
<script>
$("#b1").on("click", function () {
$.ajax({
url:"/ajax_add/",
type:"GET",
data:{
"i1":$("#i1").val(),
"i2":$("#i2").val()
},
success:function (data) {
$("#i3").val(data);
}
})
})
</script>
</body>
</html> # views.py
def ajax_demo1(request):
return render(request, "ajax_demo1.html") def ajax_add(request):
i1 = int(request.GET.get("i1"))
i2 = int(request.GET.get("i2"))
ret = i1 + i2
return JsonResponse(ret, safe=False) urls.py
urlpatterns = [
...
url(r'^ajax_add/', views.ajax_add),
url(r'^ajax_demo1/', views.ajax_demo1),
...
]
常见应用情景
搜索引擎根据用户输入的关键字,自动提示检索关键字。
注册时候的用户名的查重
整个过程中页面没有刷新,只是刷新页面中的局部位置
当请求发出后,浏览器还可以进行其他操作,无需等待服务器的响应
AJAX的优缺点
优点:
- AJAX使用JavaScript技术向服务器发送异步请求;
- AJAX请求无须刷新整个页面;
- 因为服务器响应内容不再是整个页面,而是页面中的部分内容,更加专一
缺点 :
- 请求杂乱且数量增加,对服务器的压力增加
传统方式 实现 AJAX
common.js
function createXhr(){
var xhr = null;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject("Microsoft.XMLHttp");
}
return xhr;
}
01-ajax-get.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button onclick="btnAjx()">点击发送 ( ajax )</button>
<a href="/01-server">发生 ( 非 ajax )</a>
<div id="show">123</div> <script src="/static/js/common.js"></script>
<script src="/static/js/jquery-1.11.3.js"></script> </body>
</html> <script>
function btnAjx() {
// 1.获取 xhr 对象
var xhr = createXhr();
// 2.创建请求
xhr.open('get', '/01-server', true);
// 3.设置回调函数
xhr.onreadystatechange = function () {
// 判断 readyState 以及 status 值
if (xhr.readyState == 4 && xhr.status == 200) {
// 接收响应数据
var resT = xhr.responseText;
$("#show").html(resT);
}
}
// 4.发送请求
xhr.send(null);
}
</script>
app.py
from flask import Flask, render_template app = Flask(__name__) @app.route('/01-ajax-get')
def ajax_get():
return render_template("01-ajax-get.html") @app.route('/01-server')
def server01():
return "这是使用 ajax 方式发送的请求" if __name__ == '__main__':
app.run()
可见较为繁琐. 需要手动写一个 创建方法, 然后ajax 的参数写入也较为麻烦,
回调方法还需要进行自行的状态判断, 此方法了解即可.
jQuery实现的AJAX
语法
settings 本次ajax请求需要的所有的参数,值为 JS对象
$.ajax(url[,settings]);
常用参数
url 字符串,表示异步请求的地址
type 字符串,表示的是请求方式, get 或 post
data 传递到服务器端的参数 ( 字符串 / json 对象 )
async 使用异步还是同步的方式发送请求
- true : 使用异步的方式
- false : 使用同步的方式
dataType 字符串,表示的是响应回来的数据的格式
- 'html'
- 'xml'
- 'text'
- 'script'
- 'json' 响应回来的数据时JSON类型的
- 'jsonp' 跨域的时候使用
- success 请求和响应成功后的回调函数
success 成功拿到数据后的进行的回调函数
error 请求或响应失败时的回调函数
beforeSend 发送请求之前执行的回调函数
如果该函数中return false 的话则终止请求的发送
function(data){} 方法. data 表示回传的数据, 必须配合上面三个来
全部参数
名称 | 值/描述 |
---|---|
async | 布尔值,表示请求是否异步处理。默认是 true。 |
beforeSend(xhr) | 发送请求前运行的函数。 |
cache | 布尔值,表示浏览器是否缓存被请求页面。默认是 true。 |
complete(xhr,status) | 请求完成时运行的函数(在请求成功或失败之后均调用,即在 success 和 error 函数之后)。 |
contentType | 发送数据到服务器时所使用的内容类型。默认是:"application/x-www-form-urlencoded"。 |
context | 为所有 AJAX 相关的回调函数规定 "this" 值。 |
data | 规定要发送到服务器的数据。 |
dataFilter(data,type) | 用于处理 XMLHttpRequest 原始响应数据的函数。 |
dataType | 预期的服务器响应的数据类型。 |
error(xhr,status,error) | 如果请求失败要运行的函数。 |
global | 布尔值,规定是否为请求触发全局 AJAX 事件处理程序。默认是 true。 |
ifModified | 布尔值,规定是否仅在最后一次请求以来响应发生改变时才请求成功。默认是 false。 |
jsonp | 在一个 jsonp 中重写回调函数的字符串。 |
jsonpCallback | 在一个 jsonp 中规定回调函数的名称。 |
password | 规定在 HTTP 访问认证请求中使用的密码。 |
processData | 布尔值,规定通过请求发送的数据是否转换为查询字符串。默认是 true。 |
scriptCharset | 规定请求的字符集。 |
success(result,status,xhr) | 当请求成功时运行的函数。 |
timeout | 设置本地的请求超时时间(以毫秒计)。 |
traditional | 布尔值,规定是否使用参数序列化的传统样式。 |
type | 规定请求的类型(GET 或 POST)。 |
url | 规定发送请求的 URL。默认是当前页面。 |
username | 规定在 HTTP 访问认证请求中使用的用户名。 |
xhr | 用于创建 XMLHttpRequest 对象的函数。 |
实例
HTML
<script>
$("#ajaxTest").click(function () {
$.ajax({
url: "/ajax_test/",
type: "POST",
data: {username: "Q1mi", password: 123456},
success: function (data) {
alert(data)
}
})
})
</script>
views.py
def ajax_test(request):
user_name = request.POST.get("username")
password = request.POST.get("password")
print(user_name, password)
return HttpResponse("OK")
urls.py
urlpatterns = [
...
url(r'^ajax_test/', views.ajax_test),
...
]
注意
$.ajax 参数
data参数中的键值对,如果值值不为字符串,需要将其转换成字符串类型。
$("#b1").on("click", function () {
$.ajax({
url:"/ajax_add/",
type:"GET",
data:{
"i1":$("#i1").val(),
"i2":$("#i2").val(),
"hehe": JSON.stringify([1, 2, 3])},
success:function (data) {
$("#i3").val(data);
}
})
})
AJAX请求如何设置csrf_token
form 表单提提交数据必须要带scrfToken,哪怕在ajax里面提交也许带这一字段才可以
方法1
普通的 form 表单的 post 方式提交需要写一个 {% csrf_token %} 会自动生成一个 隐藏的 input 标签
跨域请求的时候需要此标签的的 csrfmiddlewaretoken 值
直接通过 jquery 方式取出此标签中的 csrfmiddlewaretoken 值放在data 中传递即可
$.ajax({
url: "/cookie_ajax/",
type: "POST",
data: {
"username": "Q1mi",
"password": 123456,
"csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val() // 使用jQuery取出csrfmiddlewaretoken的值,拼接到data中
},
success: function (data) {
console.log(data);
}
})
方法2
单独写一个CSS文件(my_ajax_csrf.css)里面写下面代码
每次有AJAX 的时候就页面引用一下,其他什么都不用做了.
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);
}
}
});
方法3
当向服务器发送一次 post 请求但是并不是通过 form 的方式, 但是只要是 post方式 数据的提交依然是需要 csrf_token
但是不是 form 的方式也么办法在页面中直接加 {% csrf_token %}, 所以也没办法通过{% csrf_token %}生成的隐藏标签来取其值
只能在 ajax 中携带的数据中直接加一个 csrfmiddlewaretoken: '{{csrf_token}}' 也可以实现
$('.jsDeleteFav_course').on('click', function () {
var _this = $(this),
favid = _this.attr('data-favid');
$.ajax({
cache: false,
type: "POST",
url: "/org/add_fav/",
data: {
fav_type: 1,
fav_id: favid,
csrfmiddlewaretoken: '{{csrf_token}}'
},
async: true,
success: function (data) {
Dml.fun.winReload();
}
});
});
ajax 上传文件
ajax 对于 上传文件 的时候一样 有特殊的操作
需要加两个参数
- processData: false,
- contentType: false,
以及
- data 必须是 FormDate 类型 不能再手动创建一个随意的 data 了
具体示例可见综合示例中的 头像文件上传
AJAX 注册综合示例
ajax 注册示例 # 注册的视图函数
def register(request):
if request.method == "POST":
ret = {"status": 0, "msg": ""}
form_obj = forms.RegForm(request.POST)
print(request.POST)
# 帮我做校验
if form_obj.is_valid():
# 校验通过,去数据库创建一个新的用户
# 传过来的字段里面有个 re_password 字段是无法入库的给去掉
# 关于这个 cleaned_data 的功能为提取出来字典里面的值
form_obj.cleaned_data.pop("re_password")
avatar_img = request.FILES.get("avatar")
# 因为现在的userinfo
models.UserInfo.objects.create_user(**form_obj.cleaned_data, avatar=avatar_img)
ret["msg"] = "/index/"
return JsonResponse(ret)
else:
print(form_obj.errors)
ret["status"] = 1
ret["msg"] = form_obj.errors
print(ret)
print("=" * 120)
return JsonResponse(ret)
# 生成一个form对象
form_obj = forms.RegForm()
print(form_obj.fields)
return render(request, "register.html", {"form_obj": form_obj}) // AJAX提交注册的数据
<script>
$("#reg-submit").click(function () {
// 取到用户填写的注册数据,向后端发送AJAX请求
var formData = new FormData();
formData.append("username", $("#id_username").val());
formData.append("password", $("#id_password").val());
formData.append("re_password", $("#id_re_password").val());
formData.append("email", $("#id_email").val());
// 上传文件的数据需要用 files 拿到
formData.append("avatar", $("#id_avatar")[0].files[0]);
formData.append("csrfmiddlewaretoken", $("[name='csrfmiddlewaretoken']").val()); $.ajax({
url: "/reg/",
type: "post",
// 上传文件的时候需要加这两个 fales
processData: false,
contentType: false,
data: formData,
success:function (data) {
if (data.status){
// 有错误就展示错误
// console.log(data.msg);
// 将报错信息填写到页面上
$.each(data.msg, function (k,v) {
// console.log("id_"+k, v[0]);
// console.log($("#id_"+k));
// 链式操作 先加值然后找父类 加属性
$("#id_"+k).next("span").text(v[0]).parent().parent().addClass("has-error");
}) }else {
// 没有错误就跳转到指定页面
location.href = data.msg;
}
}
})
}); // 将所有的input框绑定获取焦点的事件,将所有的错误信息清空
$("form input").focus(function () {
$(this).next().text("").parent().parent().removeClass("has-error");
}) </script>
序列化
Django内置的serializers
可以更加便携进行序列化,当然可以用 json 模块完成
待补充 这个方法是内置的比较粗糙的,实际上很少被使用.
from django.core import serializers def books_json(request):
book_list = models.Book.objects.all()[0:10] ret = serializers.serialize("json", book_list) # 第一个参数为转换的格式,后一个参数为被转换的变量
return HttpResponse(ret)
Django JSON,AJAX的更多相关文章
- uploadify ,前端页面获取值,json,ajax
针对这几月的技术,做一次小总结 上传控件uploadify function inexel() { $("#btnExcel").uploadify({ 'method': 'po ...
- java:(json,ajax,path,Oracle的分页实例,Filter拦截器)
1.json: <%@ page language="java" import="java.util.*" pageEncoding="UTF- ...
- Python Django缓存,信号,序列化,文件上传,Ajax登录和csrf_token验证
本节内容 models操作 Django的缓存 请求方式 序列化 Form 配合Ajax实现登录认证 上传文件 Ajax csrf_token验证方式 1 models操作 单表查询: curd(增 ...
- django设置并获取cookie/session,文件上传,ajax接收文件,post/get请求及跨域请求等的方法
django设置并获取cookie/session,文件上传,ajax接收文件等的方法: views.py文件: from django.shortcuts import render,HttpRes ...
- 还在用Json完成Ajax,改用Beetl吧
原文链接:https://blog.csdn.net/xiandafu/article/details/44216905 作者:Beetl作者,闲大赋 浏览器通过AJAX,服务器返回json数据,无刷 ...
- Jackson 转换JSON,SpringMVC ajax 输出,当值为null或者空不输出字段@JsonInclude
当我们提供接口的时候, Ajax 返回的时候,当对象在转换 JSON (序列化)的时候,值为null或者为“” 的字段还是输出来了.看上去不优雅. 现在我叙述三种方式来控制这种情况. 注解的方式( @ ...
- Jsonp 关键字详解及json和jsonp的区别,ajax和jsonp的区别
为什么要用jsonp? 相信大家对跨域一定不陌生,对同源策略也同样熟悉.什么,你没听过?没关系,既然是深入浅出,那就从头说起. 假如我写了个index页面,页面里有个请求,请求的是一个json数据(不 ...
- 什么是Ajax和JSON,它们的优缺点
什么是Ajax??? 术语Ajax用来描述一组技术,它使浏览器可以为用户提供更为自然的浏览体验. Ajax它是“Asynchronous JavaScript + XML的简写” 定义Ajax: Aj ...
- AJAX发送json,SpringMVC 接收JSON,@RequestBody
需求:JQuery ajax前台,采用 POST请求 发送json,后台使用SpringMVC接收json并处理 前台: $.ajax({ url:"请求地址", type:&qu ...
随机推荐
- 国外线下技术俱乐部建设(1) - Belgrade Python技术俱乐部2019-01-25活动感悟
这是<国外线下技术俱乐部建设>系列文章之一. 虽然之前接触过Belgrade的.NET技术俱乐部,但是它最近活动要春节后了. 出于观摩别人是怎么搞线下社区的心态,还有自己也有在用Pyt ...
- AngularJS学习之旅—AngularJS 过滤器(七)
1.AngularJS 过滤器 过滤器可以使用一个管道字符(|)添加到表达式和指令中. AngularJS 过滤器可用于转换数据: 过滤器 描述 currency 格式化数字为货币格式. filter ...
- c/c++ 多线程 unique_lock的使用
多线程 unique_lock的使用 unique_lock的特点: 1,灵活.可以在创建unique_lock的实例时,不锁,然后手动调用lock_a.lock()函数,或者std::lock(lo ...
- iOS开发者学习Flutter
Flutter for iOS 开发者 本文档适用那些希望将现有 iOS 经验应用于 Flutter 的开发者.如果你拥有 iOS 开发基础,那么你可以使用这篇文档开始学习 Flutter 的开发. ...
- Python基础之面对对象进阶
阅读目录 isinstance和issubclass 反射 setattr delattr getattr hasattr __str__和__repr__ __del__ item系列 __geti ...
- C#基础知识之字符串比较方法:“==”操作符;RefernceEquals;String.Equals方法;String.Compare方法;String.CompareOrdinal方法。
一.“==”操作符:String.Equals:ReferenceEquals 方法 1.在编程中实际上我们只需要这两种比较,c#中类型也就这两种 (1)值类型的比较:一般我们就是判断两个值类型实例各 ...
- .NET CORE学习笔记系列(2)——依赖注入【3】依赖注入模式
原文:https://www.cnblogs.com/artech/p/net-core-di-03.html IoC主要体现了这样一种设计思想:通过将一组通用流程的控制权从应用转移到框架中以实现对流 ...
- Linux下配置nfs并远程挂载实战探讨
简单介绍: nfs是网络文件系统,允许一个节点通过网络访问远程计算机的文件系统,远程文件系统可以被直接挂载到本地,文件操作和本地没有区别,如果是局域网的nfs那么io的性能也可以保证 nfs是Netw ...
- (三)Installation
Elasticsearch requires at least Java 8. Specifically as of this writing, it is recommended that you ...
- 使用serialize时多数据传递
class CartList(APIView): #定义编辑方法 def post(self,request): username = request.POST.get('username') # p ...