一.Ajax简介

在此之前你一定需要先学习下JavaScript JSON 可见:

前端学习 之 JavaScript 之 JSON

1、简单介绍

我们以前知道的前端向后端发送数据的方式有:

  GET:地址栏、a标签、Form表单

  POST:Form表单

那么现在我们在学习一种:那就是ajax

ajax:也是前端向后端发送数据的一种方式

AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)。

AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML,现在更多使用json数据)。

同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;

异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。

Ajax的特点(优点)

  异步交互: 当请求发出后,浏览器还可以进行其他操作,无需等待服务器的响应!

  局部刷新:    整个过程中页面没有刷新,只是刷新页面中的局部位置而已!

二.jQuery实现Ajax

前提是在Django框架上,并已经做相关的基础配置后。

前端代码:

<body>
{% csrf_token %}
<p><input type="text" class="user" placeholder="用户名"></p>
<p><input type="password" placeholder="密码" class="pwd"></p>
<button id="ajaxTest">AJAX 测试</button>
<script src="/static/js/jquery.js"></script>
<script>
$("#ajaxTest").click(function () {
var username = $(".user").val();
var password = $(".pwd").val();
console.log(username, password);
$.ajax({
url: "/jq_ajax/",
type: "POST",
data: {
csrfmiddlewaretoken: $("input[name='csrfmiddlewaretoken']").val(),
user: username,
pwd: password,
},
success: function (res) {
alert("hahaha")
//未来接收服务端返回值,来进行做判断做的相应的反应
if (res == "ok"){
alert("okla")
}else{
alert("buok.")
}
}
})
})
</script>
</body>

后端代码:

def jq_ajax(request):

    # if request.method == "GET":

    if request.is_ajax():

        username = request.POST.get("user")

        password = request.POST.get("pwd")

        print(username, password)

        return HttpResponse("okddd")

return render(request, "jq_ajax.html")

views.py

三.Ajax案例

1.用户名是否已被注册

在注册表单中,当用户填写了用户名后,把光标移开后,会自动向服务器发送异步请求。服务器返回true或false,返回true表示这个用户名已经被注册过,返回false表示没有注册过。客户端得到服务器返回的结果后,确定是否在用户名文本框后显示“用户名已被注册”的错误信息!

2.基于Ajax进行登录验证

用户在表单输入要注册用户名,用户单击框外,网页通过Ajax提交给服务器,服务器验证用户名是否存在后返回响应信息,客户端通过响应信息做出相应的提醒,可以注册不提醒,否则在页面上显示登录用户名已经被使用!

四.Ajax实现一个计算案例

前端代码为:

<body>

<h3>计算案例</h3>

{% csrf_token %}

<input type="text" id="i1"> + <input type="text" id="i2"> = <input type="text" id="i3"> <button id="btn1">计算</button>

<span id="err"></span>

<script src="/static/js/jquery.js"></script>

<script>

$("#btn1").click(function () {

var i1 = $("#i1").val()

var i2 = $("#i2").val()

$.ajax(

{

url:"/add_test/",

type: "post",

data:{

csrfmiddlewaretoken: $("input[name='csrfmiddlewaretoken']").val(),

i1:i1,

i2:i2,

},

success : function (ret) {

{#var ret = JSON.parse(ret);   //在django后端用的是JsonResponse就不用反序列化了#}

console.log(ret,typeof ret);

if (ret.status){

$("#i3").val(ret.msg);

}else {

$("#err").text(ret.msg);

// 过三秒后自动消失

setTimeout(function () {

$("#err").text("");

},3000)

}

{#$("#i3").val(res)#}

}

}

)

})

</script>

</body>

后端django视图函数为:

from django.http import JsonResponse

import json

def add_test(request):

if request.is_ajax():

ret = {"status": 1, "msg": None}

num1 = request.POST.get("i1")

num2 = request.POST.get("i2")

try:

res = int(num1) + int(num2)

ret['msg'] = res

except ValueError as e:

ret['status'] = 0

ret['msg'] = "请核对输入的数据的合法性"

# return HttpResponse(json.dumps(ret))

//如果用到 JsonResponse就不需要序列化了

return JsonResponse(ret)

return render(request, "add_test.html")

五.基于Ajax上传json数据

1.前端模板代码

<body>

{% csrf_token %}

<h3>json 数据</h3>

<p><input type="text" class="user" placeholder="用户名"></p>

<p><input type="password" placeholder="密码" class="pwd"></p>

<button id="ajaxTest">AJAX json 测试</button>

<script src="/static/js/jquery.js"></script>

<script>

$("#ajaxTest").click(function () {

var user = $(".user").val();

var pwd = $('.pwd').val();

$.ajax({

url: "",

type: 'POST',

//注意T大写

contentType: "json",

headers: {"X-CSRFToken": $("input[name='csrfmiddlewaretoken']").val()}, // 在请求头中添加csrf

// json 前端的序列化方式

data: JSON.stringify({

user: user,

pwd: pwd,

{#csrfmiddlewaretoken: $("input[name='csrfmiddlewaretoken']").val(),#}

}),

success: function (ret) {

console.log(ret)

}

})

})

</script>

</body>

2.后端视图代码

def json_test(request):

if request.is_ajax():

print(request.POST)  # json时,post为空

print(request.body)  # 如果前端没有序列化就是原生请求体内容,如果序列化的就是字典(其实是byte类型)

data_str = request.body.decode()

data = json.loads(data_str)

print(data, type(data))  # 是字典类型

# print(data.get('user'), type(data))

return HttpResponse("ok")

return render(request, "json_test.html")

总结:

前端:

$.ajax({

url: "", # 默认往当前url提交

type: "post", #请求方式

contentType: "json",

headers: {"X-CSRFToken": $("input[name='csrfmiddlewaretoken']").val()}, // 在请求头中添加csrf

data: JSON.stringify({

key1: val1,

key2: val2,

...

},

success: function(ret){

console.log(ret)

}

})

后端:

request.POST     # 为空

request.body    # b'{"user":"alex","pwd":"123"}'

1. 转换成字符串

2. 反序列化  # dict1 = json.loads(request.body.decode())

六.基于form表单上传文件

1.前端模板代码

<body>

<h3>文件上传</h3>

<form action="" method="post" enctype="multipart/form-data">

    {% csrf_token %}

    <input type="file" name="f_name">

    <input type="submit" value="上传">

</form>

</body>

2.后端视图代码

import os

def upload(request):

if request.method == "GET":

return render(request, 'upload.html')

else:

print(request.POST)   # <class 'str'> 没有意义

# print(request.body) #  enctype="multipart/form-data"   ,会报错

print(request.FILES.get('f_name'), type(request.FILES.get('f_name')))

# 类型是一个对象

file_obj = request.FILES.get('f_name')

print(file_obj.name)

with open(os.path.join("media",file_obj.name),mode="wb") as fp:

for i in file_obj:

fp.write(i)

return HttpResponse("ok")

 七.基于Ajax请求上传文件

1.前端模板代码

<body>

<h3>ajax 文件上传</h3>

{% csrf_token %}

<input type="file" id="file_id">

<input type="button" value="上传" id="btn1">

<script src="/static/js/jquery.js"></script>

<script>

$("#btn1").click(function () {

// 封装数据

let formdata = new FormData();

formdata.append("csrfmiddlewaretoken", $("[name='csrfmiddlewaretoken']").val());

// 将f_name 传到后端当字典的键,另外一个则是一个对象

formdata.append('f_name', $("#file_id")[0].files[0]);

// 处理ajax请求

$.ajax({

url: "",

type: "POST",

processData: false,  // 告诉jQuery不要去处理发送的数据

contentType: false,  // 告诉jQuery不要去设置Content-Type请求头

data: formdata,

// 成功后返回的数据

success: function (ret) {

console.log(ret)

}

})

})

</script>

</body>

获取页面的文件对象步骤:

2.后端视图代码

def upload_ajax(request):

if request.method == "GET":

return render(request, "upload_ajax.html")

else:

print(request.POST)

# print(type(request.POST.get("fi_name1")))  #<class 'str'> 没有意义

# print(request.body)   #  enctype="multipart/form-data"   ,会报错

print(request.FILES)

print(request.FILES.get('f_name'))

print(type(request.FILES.get('f_name')))

file_obj = request.FILES.get('f_name')

print(file_obj.name)

with open(os.path.join("media", file_obj.name), "wb") as f:

for i in file_obj:

f.write(i)

return HttpResponse("ok")

后端视图代码基本和基础表单上传文件的一样。

八.ContentType 类型

ContentType指的是请求体的编码类型,常见的类型共有3种:

1.application/x-www-form-urlencoded(默认类型)

    这应该是最常见的 POST 提交数据的方式了。浏览器的原生 <form> 表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。请求类似于下面这样(无关的请求头在本文中都省略掉了):

POST http://www.example.com HTTP/1.1

Content-Type: application/x-www-form-urlencoded;charset=utf-8

user=hsz&age=22

2.multipart/form-data(用于form上传文件时)

这又是一个常见的 POST 数据提交的方式。我们使用表单上传文件时,必须让 <form> 表单的 enctype 等于 multipart/form-data。直接来看一个请求示例:

POST http://www.example.com HTTP/1.1

Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA

------WebKitFormBoundaryrGKCBY7qhFd3TrwA

Content-Disposition: form-data; name="user"

hsz

------WebKitFormBoundaryrGKCBY7qhFd3TrwA

Content-Disposition: form-data; name="file"; filename="chrome.png"

Content-Type: image/png

PNG ... content of chrome.png ...

------WebKitFormBoundaryrGKCBY7qhFd3TrwA--

这个例子稍微复杂点。首先生成了一个 boundary 用于分割不同的字段,为了避免与正文内容重复,boundary 很长很复杂。然后 Content-Type 里指明了数据是以 multipart/form-data 来编码,本次请求的 boundary 是什么内容。消息主体里按照字段个数又分为多个结构类似的部分,每部分都是以 --boundary 开始,紧接着是内容描述信息,然后是回车,最后是字段具体内容(文本或二进制)。如果传输的是文件,还要包含文件名和文件类型信息。消息主体最后以 --boundary-- 标示结束。关于 multipart/form-data 的详细定义,请前往 rfc1867 查看。

    这种方式一般用来上传文件,各大服务端语言对它也有着良好的支持。

    上面提到的这两种 POST 数据的方式,都是浏览器原生支持的,而且现阶段标准中原生 <form> 表单也只支持这两种方式(通过 <form> 元素的 enctype 属性指定,默认为 application/x-www-form-urlencoded。其实 enctype 还支持 text/plain,不过用得非常少)。

随着越来越多的 Web 站点,尤其是 WebApp,全部使用 Ajax 进行数据交互之后,我们完全可以定义新的数据提交方式,给开发带来更多便利。

3.application/json(用于json)

application/json 这个 Content-Type 作为响应头大家肯定不陌生。实际上,现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。由于 JSON 规范的流行,除了低版本 IE 之外的各大浏览器都原生支持 JSON.stringify,服务端语言也都有处理 JSON 的函数,使用 JSON 不会遇上什么麻烦。

    JSON 格式支持比键值对复杂得多的结构化数据,这一点也很有用。记得我几年前做一个项目时,需要提交的数据层次非常深,我就是把数据 JSON 序列化之后来提交的。不过当时我是把 JSON 字符串作为 val,仍然放在键值对里,以 x-www-form-urlencoded 方式提交。

Django学习 之后端视图与ajax的更多相关文章

  1. Django学习笔记(14)——AJAX与Form组件知识补充(局部钩子和全局钩子详解)

    我在之前做了一个关于AJAX和form组件的笔记,可以参考:Django学习笔记(8)——前后台数据交互实战(AJAX):Django学习笔记(6)——Form表单 我觉得自己在写Django笔记(8 ...

  2. Django学习笔记之视图高级-HTTP请求与响应

    Django限制请求method 常用的请求method GET请求 GET请求一般用来向服务器索取数据,但不会向服务器提交数据,不会对服务器的状态进行更改.比如向服务器获取某篇文章的详情. POST ...

  3. Django 学习笔记(五) --- Ajax 传输数据

    人生苦短 ~ Tips:仅适用于 Python 3+(反正差别不大,py2 改改也能用).因为据 Python 之父 Guido van Rossum 说会在 2020 年停止对 Python 2 的 ...

  4. Django学习---路由url,视图,模板,orm操作

    Django请求周期 url ->  路由系统  ->函数或者类 -> 返回字符串 或者 模板语言 Form表单提交: 点击提交 -> 进入url系统  ->  执行函数 ...

  5. Django学习路35_视图使用方法(复制的代码) + 简单总结

    from django.shortcuts import render,redirect from django.http import HttpResponse,JsonResponse from ...

  6. Django学习日记06_视图_URLconf、View

    URLconf Django通过URLconf来响应网页请求,在项目设置settings.py中,设定了ROOT_URLCONF值来指定默认的URLconf(即mysite.urls),当HTTPRe ...

  7. Django学习笔记之视图高级-CSV文件生成

    生成CSV文件 有时候我们做的网站,需要将一些数据,生成有一个CSV文件给浏览器,并且是作为附件的形式下载下来.以下将讲解如何生成CSV文件. 生成小的CSV文件 这里将用一个生成小的CSV文件为例. ...

  8. Django学习笔记之视图高级-类视图

    类视图 在写视图的时候,Django除了使用函数作为视图,也可以使用类作为视图.使用类视图可以使用类的一些特性,比如继承等. View django.views.generic.base.View是主 ...

  9. Django学习之 - 基础视图函数

    视图:Views 获取用户请求的方法: 1: request.GET 2: request.POST 3: request.FILES # checkbox 等多选文件 4:request.POST. ...

随机推荐

  1. 5、Maven-构建配置文件

    什么是构建配置文件? 配置文件是一组配置的集合,用来设置或者覆盖Maven构建的默认设置, 使用配置文件可以为不同的环境定制构建过程,例如Producation和Development环境. Prof ...

  2. Vue基础笔记2

    目录 1. 如何获取Vue对象中的成员? 2. pre指定 3. for循环 4. todolist 5. 分隔符 6. computed 计算后的 7. vue的生命周期(讲解不全) 8. watc ...

  3. MySQLroot密码的恢复方法

    MySQLroot密码的恢复方法 有可能你的系统没有 safe_MySQLd 程序(比如我现在用的 ubuntu操作系统, apt-get安装的MySQL) , 下面方法可以恢复 1.停止MySQLd ...

  4. SpringCloud全家桶学习之分布式配置中心----Config(七)

    一.概述 (1)背景 微服务意味着将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中出现大量的服务.由于每个服务都需要配置必要的配置信息才能运行,所以一套集中式的.动态的配置管理 ...

  5. placeholder样式

    .mdwh_txtmod_tp_inpshad input::-webkit-input-placeholder { /* WebKit browsers */ color: #cccccc; } . ...

  6. 缓存验证Last-Modified和Etag的使用

    缓存工作示意图: 在http协议里面,数据的验证方式,主要有两个验证头:Last-Modified 和 Etag. Last-Modified 配合Last-Modified-Since或者If-Un ...

  7. 第三方控件引起的"类型Universe无法解析程序集"的血案

    前一阵子在项目中添加了IrisSkin2皮肤控件,今天用VS打开悲剧了. 提示"类型Universe无法解析程序集:System.Design,Version=2.0.0.0,Culture ...

  8. ZOJ1008 Gnome Tetravex

    DFS+剪枝~ #include<bits/stdc++.h> using namespace std; ][]; int N; int cnt; ]; ]; unordered_map& ...

  9. linux磁盘管理2-raid,lvm

    raid 多个磁盘合成一个“阵列”来提供更好的性能.冗余,或者两者都提供 提高IO能力 磁盘并行读写 提高耐用性 磁盘冗余来实现 级别:多块磁盘组织在一起的工作方式有所不同 RAID实现的方式 外接式 ...

  10. CSS创意与视觉表现

    视觉效果 CSS代码: .cover { padding: 36% 50%; background: linear-gradient(to right, white 50%, black calc(5 ...