Ajax相关知识

目录

一.前后端传输数据的编码格式(contentType)

1.form表单

2.编码格式

3.Ajax

4.代码演示

后端

前端HTML

二.Ajax发送JSON格式数据

1.引入

后端

前端

2.后端

接收到的数据为空

解决办法

3.request方法判断Ajax

4.总结

前端在通过ajax请求发送数据的时候,一定要注参数修改

数据是真正的JSON格式数据

Django后端不会帮我们处理JSON格式数据,需要自己手动处理request.body中的数据

三.Ajax发送文件数据

1.Ajax发送文件数据需要借助js内置对象formdata

前端

后端

发送文件数据的格式

2.结论

Ajax发送文件数据需要利用内置对象FormData

需要指定两个关键性的参数

Django后端能直接自动识别到FormData对象

四.分页

1.前言

2.自定义分页器封装代码

3.后端使用方法

4.前端使用方法


一.前后端传输数据的编码格式(contentType)

主要研究POST请求数据的编码格式

因为GET请求数据就是直接放在url后面的

  • 可以朝后端发送post请求的方式
    • form请求
    • ajax请求

1.form表单

  • 前后端传输数据的格式
    • urlencoded
    • formdata
    • json

2.编码格式

  • form表单默认的编码格式是urlencoded
    • 通过查看请求头中的Content-Type参数
text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding:gzip, deflate, br
Accept-Language:zh-CN,zh;q=0.9,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Content-Length:27
Content-Type:application/x-www-form-urlencoded
  • 携带数据格式
username=666666&password=66
  • Django后端针对urlencoded编码格式的数据会自动帮我们解析封装到request.POST中
  • 如果编码格式改为formdata,那么针对普通的键值对还是解析到request.POST中,而其他文件格式的数据解析到request.FILES中
  • form表单无法发送json格式数据

3.Ajax

Accept:*/*
Accept-Encoding:gzip, deflate, br
Accept-Language:zh-CN,zh;q=0.9,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Content-Length:31
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
  • 默认的编码格式是urlencoded
  • 数据格式
username=dream&password=1314521
  • Django后端针对urlencoded编码格式的数据会自动帮我们解析封装到request.POST中--->username = dream&password=123456

4.代码演示

后端

def index(request):if request.method == 'POST':print(request.POST)print(request.FILES)return render(request, 'index.html')

前端HTML

<form action="" method="post" enctype="multipart/form-data"><p>username: <input type="text" name="username" class="form-control"></p><p>password: <input type="password" name="password" class="form-control"></p><p>file: <input type="file"></p><p><input type="submit" class="btn btn-success"></p><p><input type="button" class="btn btn-danger" value="按钮" id="d1"></p>
</form><script>$("#d1").click(function () {$.ajax({url: '',type: 'POST',data: {"username": "dream", "password": 1314521},success: function (args) {},})})
</script>

二.Ajax发送JSON格式数据

前后端传输数据的时候一定要保证编码格式数据与真正的数据格式是一致的

1.引入

后端

def ab_json(request):if request.method == 'POST':print(request.POST) #<QueryDict: {}>return render(request, 'ab_json.html')

前端

<button class="btn btn-danger" id="d1">点我</button><script>$('#d1').click(function () {$.ajax({url: '',type: 'post',// 前端数据转JSON格式数据 :JSON.stringifydata: JSON.stringify({"username": "dream", "password": 521521}),// 不指定参数,默认就是 urlencodedcontentType: 'application/json',success: function (args) {}})})
</script>
  • 请求标头携带的数据格式
    • 已成功转换为JSON格式
{"username":"dream","password":521521}

2.后端

接收到的数据为空

def ab_json(request):if request.method == 'POST':print(request.POST) #<QueryDict: {}>return render(request, 'ab_json.html')

Django 针对JSON格式的数据不会做任何处理

针对JSON格式的数据需要自己手动处理

解决办法

def ab_json(request):print(request.is_ajax())  # Trueif request.method == 'POST':print(request.POST)  # <QueryDict: {}>print(request.body)  # 返回的是二进制数据 :b'{"username":"dream","password":521521}'# 针对JSON格式的数据需要自己手动处理json_bytes = request.body# (1)方式一:先解码 再转换数据格式json_str = json_bytes.decode('utf-8')json_dict = json.loads(json_str)print(json_dict, type(json_dict))  # {'username': 'dream', 'password': 521521} <class 'dict'># (2)方式二:json.loads(二进制数据) 内部可以自动解码再反序列化json_dict_loads = json.loads(json_bytes)print(json_dict_loads, type(json_dict_loads))  # {'username': 'dream', 'password': 521521} <class 'dict'>return render(request, 'ab_json.html')

3.request方法判断Ajax

request.is_ajax()

返回当前请求是否是ajax请求,返回布尔值

print(request.is_ajax()) 正常浏览器网址回车提交的是 GET 请求 - 结果是False 当我们发送ajax请求后 - 结果是True

4.总结

前端在通过ajax请求发送数据的时候,一定要注参数修改

// 不指定参数,默认就是 urlencoded
contentType: 'application/json',

数据是真正的JSON格式数据

发送的数据一定要符合JSON格式

或经过JSON序列化再传输

Django后端不会帮我们处理JSON格式数据,需要自己手动处理request.body中的数据

通过Ajax传过来的数据是二进制数据

在request.body中要经过自己的反序列化才能拿到我们想要的数据

三.Ajax发送文件数据

1.Ajax发送文件数据需要借助js内置对象formdata

前端

<p>username: <input type="text" name="username" id="d1"></p>
<p>password: <input type="password" name="password" id="d2"></p>
<p>file: <input type="file" id="d3"></p><button id="btn" class="btn btn-danger">提交</button><script>// 点击按钮向后端发送普通键值对数据和文件数据$("#btn").on('click', function () {// (1)先生成一个内置对象let formDataObj = new FormData();// (2)支持添加普通的键值对formDataObj.append('username', $("#d1").val());formDataObj.append('password', $("#d2").val());// (3)支持添加文件对象 ---> 先拿到标签对象 ----> 再拿到文件对象formDataObj.append('myfile', $("#d3")[0].files[0]);// (4)基于Ajax,将文件对象发送给后端$.ajax({url: '',type: 'post',// 直接将对象放到data里面即可data: formDataObj,// Ajax发送文件必须添加的两个参数// 不需要使用任何编码 -  Django后端能自动识别 formdata 对象contentType: false,// 告诉浏览器不要对我的数据进行任何处理processData: false,success: function (args) {}})})
</script>

后端

def ab_file(request):if request.is_ajax():if request.method == 'POST':print('POST::>>', request.POST)# 普通键值对放在了  request.POST   中# POST::>> <QueryDict: {'username': ['dream'], 'password': ['666']}>print('FILES::>>', request.FILES)# 文件数据放在了  request.FILES   中# FILES::>> <MultiValueDict: {'myfile': [<InMemoryUploadedFile: img.png (image/png)>]}>return render(request, 'ab_file.html')

发送文件数据的格式

// 点击按钮向后端发送普通键值对数据和文件数据
$("#btn").on('click', function () {
// (1)先生成一个内置对象
let formDataObj = new FormData();// (2)支持添加普通的键值对
formDataObj.append('username', $("#d1").val());
formDataObj.append('password', $("#d2").val());// (3)支持添加文件对象 ---> 先拿到标签对象 ----> 再拿到文件对象
formDataObj.append('myfile', $("#d3")[0].files[0]);// (4)基于Ajax,将文件对象发送给后端
$.ajax({
url: '',
type: 'post',
// 直接将对象放到data里面即可
data: formDataObj,// Ajax发送文件必须添加的两个参数
// 不需要使用任何编码 -  Django后端能自动识别 formdata 对象
contentType: false,
// 告诉浏览器不要对我的数据进行任何处理
processData: false,success: function (args) {}
})

2.结论

Ajax发送文件数据需要利用内置对象FormData

// (1)先生成一个内置对象
let formDataObj = new FormData();// (2)支持添加普通的键值对
formDataObj.append('username', $("#d1").val());
formDataObj.append('password', $("#d2").val());// (3)支持添加文件对象 ---> 先拿到标签对象 ----> 再拿到文件对象
formDataObj.append('myfile', $("#d3")[0].files[0]);

需要指定两个关键性的参数

// Ajax发送文件必须添加的两个参数
// 不需要使用任何编码 -  Django后端能自动识别 formdata 对象
contentType: false,
// 告诉浏览器不要对我的数据进行任何处理
processData: false,
  • Django后端能直接自动识别到FormData对象

    • 将内部的普通键值对自动解析并封装到request.POST中
    • 将内部的文件数据自动解析并封装到request.FILES中
print('POST::>>', request.POST)
# 普通键值对放在了  request.POST   中
# POST::>> <QueryDict: {'username': ['dream'], 'password': ['666']}>print('FILES::>>', request.FILES)
# 文件数据放在了  request.FILES   中
# FILES::>> <MultiValueDict: {'myfile': [<InMemoryUploadedFile: img.png (image/png)>]}>

四.分页

1.前言

当我们需要使用到非Django内置的第三方模块或者功能组件代码的时候,我们一般情况下会创建一个名为utils的文件夹,在该文件夹中对模块的功能进行划分

注意:样式基于bootstrap,需要引入bootstrap配置

2.自定义分页器封装代码

class Pagination(object):def __init__(self, current_page, all_count, per_page_num=2, pager_count=11):"""封装分页相关数据:param current_page: 当前页:param all_count:    数据库中的数据总条数:param per_page_num: 每页显示的数据条数:param pager_count:  最多显示的页码个数"""try:current_page = int(current_page)except Exception as e:current_page = 1if current_page < 1:current_page = 1self.current_page = current_pageself.all_count = all_countself.per_page_num = per_page_num# 总页码all_pager, tmp = divmod(all_count, per_page_num)if tmp:all_pager += 1self.all_pager = all_pagerself.pager_count = pager_countself.pager_count_half = int((pager_count - 1) / 2)@propertydef start(self):return (self.current_page - 1) * self.per_page_num@propertydef end(self):return self.current_page * self.per_page_numdef page_html(self):# 如果总页码 < 11个:if self.all_pager <= self.pager_count:pager_start = 1pager_end = self.all_pager + 1# 总页码  > 11else:# 当前页如果<=页面上最多显示11/2个页码if self.current_page <= self.pager_count_half:pager_start = 1pager_end = self.pager_count + 1# 当前页大于5else:# 页码翻到最后if (self.current_page + self.pager_count_half) > self.all_pager:pager_end = self.all_pager + 1pager_start = self.all_pager - self.pager_count + 1else:pager_start = self.current_page - self.pager_count_halfpager_end = self.current_page + self.pager_count_half + 1page_html_list = []# 添加前面的nav和ul标签page_html_list.append('''<nav aria-label='Page navigation>'<ul class='pagination'>''')first_page = '<li><a href="?page=%s">首页</a></li>' % (1)page_html_list.append(first_page)if self.current_page <= 1:prev_page = '<li class="disabled"><a href="#">上一页</a></li>'else:prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1,)page_html_list.append(prev_page)for i in range(pager_start, pager_end):if i == self.current_page:temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,)else:temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,)page_html_list.append(temp)if self.current_page >= self.all_pager:next_page = '<li class="disabled"><a href="#">下一页</a></li>'else:next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1,)page_html_list.append(next_page)last_page = '<li><a href="?page=%s">尾页</a></li>' % (self.all_pager,)page_html_list.append(last_page)# 尾部添加标签page_html_list.append('''</nav></ul>''')return ''.join(page_html_list)

3.后端使用方法

 def get_book(request):book_list = models.Book.objects.all()current_page = request.GET.get("page",1)all_count = book_list.count()page_obj = Pagination(current_page=current_page,all_count=all_count,per_page_num=10)page_queryset = book_list[page_obj.start:page_obj.end]return render(request,'booklist.html',locals())

4.前端使用方法

<div class="container"><div class="row"><div class="col-md-8 col-md-offset-2">{% for book in page_queryset %}<p>{{ book.title }}</p>{% endfor %}{{ page_obj.page_html|safe }}</div></div>
</div>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/156844.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【网络通信】浅析UDP与TCP协议的奥秘

在现代互联网中&#xff0c;UDP&#xff08;用户数据报协议&#xff09;和TCP&#xff08;传输控制协议&#xff09;是两种最常用的传输协议&#xff0c;它们被广泛应用于网络数据传输。尽管这两种协议都可以用来在网络上传输数据&#xff0c;但它们在设计目标、特点和适用场景…

如何用 GPTs 帮你写科研项目申请书?

&#xff08;注&#xff1a;本文为小报童精选文章&#xff0c;已订阅小报童或加入知识星球「玉树芝兰」用户请勿重复付费&#xff09; 需求 学生们往往会觉得&#xff0c;写开题报告是个苦差事。但他们或许不知道&#xff0c;老师们写起科研项目申请书&#xff0c;压力远比他们…

如何将Docker的构建时间减少40%

与许多公司类似&#xff0c;我们为产品中使用的所有组件构建docker映像。随着时间的推移&#xff0c;其中一些映像变得越来越大&#xff0c;我们的CI构建花费的时间也越来越长。我的目标是CI构建不超过5分钟——差不多是喝杯咖啡休息的理想时间。如果构建花费的时间超过这个时间…

OpenGeometry 开源社区特聘子虔科技云CAD专家 共建云几何内核

11月5日&#xff0c;由广东省工业和信息化厅、广东省科学技术厅、广东省教育厅、深圳市人民政府主办的2023工业软件生态大会在广东省深圳市召开。 开幕式上&#xff0c;备受关注的云几何内核开源平台——OpenGeometry开源社区正式发布。这意味着在几何引擎领域将通过开源这个模…

设计模式—命令模式

1.什么是命令模式&#xff1f; 命令模式是一种行为型设计模式&#xff0c;核心是将每种请求或操作封装为一个独立的对象&#xff0c;从而可以集中管理这些请求或操作&#xff0c;比如将请求队列化依次执行、或者对操作进行记录和撤销。 命令模式通过将请求的发送者&#xff0…

梨花声音教育,美食视频配音再次挑战味蕾

在为美食视频进行配音时&#xff0c;配音艺术家的目标是通过声音来激活观众的感官&#xff0c;唤起他们对美味佳肴的渴望&#xff0c;同时展现食物的诱人特色和烹饪的艺术性。配音应当能够描绘美食的丰富细节&#xff0c;传达烹饪的趣味性以及食材的高品质。以下是一些为美食视…

KWin、libdrm、DRM从上到下全过程 —— drmModeAddFBxxx(20)

接前一篇文章:KWin、libdrm、DRM从上到下全过程 —— drmModeAddFBxxx(19) 上一回讲解了从drm_mode_addfb2_ioctl()和drm_mode_addfb_ioctl()一步步往前追溯的全过程: drm_mode_addfb2_ioctl() / drm_mode_addfb_ioctl() ---> drm_ioctls[] ---> drm_ioctl()---> …

iOS越狱检测总结

文章目录 前言检测越狱文件私有目录检测检测越狱软件检测系统目录是否变为链接动态库检测环境变量检测系统调用检测指令集调用检测其他方式检测 前言 在之前的文章中&#xff0c;已经带大家一起制作了一个屏蔽越狱检测的Tweak。本文就和大家一起学习整理一下iOS系统中有哪些越…

MATLAB算法实战应用案例精讲-【数模应用】漫谈机器学习(三)

目录 机器学习发展历程 1. 五大流派 2. 演化的阶段 1980 年代 1990 年代到 2000 年

NGINX缓存详解之服务端缓存

服务端缓存 proxy cache属于服务端缓存,主要实现 nginx 服务器对客户端数据请求的快速响应。 nginx 服务器在接收到被代理服务器的响应数据之后,一方面将数据传递给客户端,另一方面根据proxy cache的配置将这些数据缓存到本地硬盘上。 当客户端再次访问相同的数据时,nginx…

计算机杂谈系列精讲100篇-【大模型】漫谈ChatGPT

目录 前言 几个高频面试题目 1. ChatGPT的通用性为何做得如此之好?

【Java系列】SpringBoot 集成MongoDB 详细介绍

目录 写在前面 一、步骤介绍 步骤 1: 添加 MongoDB 依赖 步骤 2: 配置 MongoDB 连接信息 步骤 3: 创建实体类 步骤 4: 创建 Repository 接口 步骤 5: 使用 Repository 进行操作 二、特殊处理 写在前面 在Spring Boot中集成MongoDB的过程相对简单&#xff0c;以下是一个…

架构探索之路-第一站-clickhouse | 京东云技术团队

一、前言 架构, 软件开发中最熟悉不过的名词, 遍布在我们的日常开发工作中, 大到项目整体, 小到功能组件, 想要实现高性能、高扩展、高可用的目标都需要优秀架构理念辅助. 所以本人尝试编写架构系列文章, 去剖析市面上那些经典优秀的开源项目, 学习优秀的架构理念来积累架构设…

在html和css中的引用svg(一)

问题&#xff1a;如何让 DIV 中的svg垂直居中&#xff1f; HTML 代码&#xff1a; <div class"content"><svg ...> ... </svg></div> CSS代码&#xff1a; .content svg { vertical-align: middle;} 实用扩展&#xff1a;如何让 DIV 中…

Spring整合其他组件

外部命名空间标签的执行流程&#xff0c;如下&#xff1a; 将自定义标签的约束与物理约束文件与网络约束名称的约束&#xff0c;以键值对形式存储到一个spring.schemas文件中&#xff0c;该文件存储在类加载路径的META-INF里&#xff0c;Spring会自动加载到 将自定义命名空间的…

极致性能优化之道之消除伪共享

“不积跬步&#xff0c;无以至千里。” 引言 在并发编程中&#xff0c;伪共享&#xff08;False Sharing&#xff09;是一种性能问题&#xff0c;特别是在多核处理器上。这个问题通常出现在多个线程同时修改彼此不同但共享同一缓存行的数据。为了解决伪共享问题&#xff0c;我…

Redis-五种数据类型

Redis基本特性 a) 非关系型的键值对数据库&#xff0c;可以根据键以O(1) 的时间复杂度取出或插入关联值 b) Redis 的数据是存在内存中的 c) 键值对中键的类型可以是字符串&#xff0c;整型&#xff0c;浮点型等&#xff0c;且键是唯一的 d) 键值对中的值类型可以是string&a…

「torch.cosine_smilarity() = 0」引发的关于cpu与gpu精度问题的探讨

前言&#xff1a;2023年11月21日下午16:00 许&#xff0c;本篇博客记录由「torch.cosine_smilarity()计算余弦相似度计算结果为0」现象引发的关于 CPU 与 GPU 计算精度的探索。 事情的起因是&#xff0c;本人在使用 torch.cosine_smilarity() 函数计算GPU上两个特征的余弦相似度…

【迅搜02】究竟什么是搜索引擎?正式介绍XunSearch

究竟什么是搜索引擎&#xff1f;正式介绍XunSearch 啥&#xff1f;还要单独讲一下啥是搜索引擎&#xff1f;不就是百度、Google嘛&#xff0c;这玩意天天用&#xff0c;还轮的到你来说&#xff1f; 额&#xff0c;好吧&#xff0c;虽然大家天天都在用&#xff0c;但是我发现&am…

移远通信推出六款新型天线,为物联网客户带来更丰富的产品选择

近日&#xff0c;移远通信重磅推出六款新型天线&#xff0c;覆盖5G、非地面网络&#xff08;NTN&#xff09;等多种新技术&#xff0c;将为物联网终端等产品带来全新功能和更强大的连接性能。 移远通信COO张栋表示&#xff1a;“当前&#xff0c;物联网应用除了需要高性能的天线…