Django商品信息模块


商品信息模块

​ 项目babys的商品模块分为商品列表页和商品详细页,本章分别从页面的业务逻辑和数据渲染的角度深入讲述如何实现网站的商品列表页和商品详细页,并深入分析页面实现过程中所使用的技术要点。

商品列表页的业务逻辑

​ 商品列表页将所有商品以一定的规则排序展示,用户可以从销量、价格、上架时间和收藏数量设置商品的排序方式,并且在页面的左侧设置分类列表,选择某一分类可以筛选出相应的商品信息,网页效果如图7-1所示。

从图7-1可以看到,商品列表页的顶部设有商品搜索功能和导航栏,这部分功能已在模板文件base.html实现了;网页顶部下方划分为3部分:分类列表、排序设置和商品列表,每部分的详细说明如下:

(1)分类列表的数据来自商品类别表,比如图7-1的“奶粉辅食”来自模型Types的firsts字段,该分类下的“进口奶粉”是模型Types的seconds字段,当用户单击网页的“进口奶粉”时,网站将会查询模型CommodityInfos的字段types等于“进口奶粉”的数据,并将符合条件的数据展示在右侧的商品列表中。

(2)排序设置是根据当前商品列表的数据进行排序显示,每次排序都会重新查询模型CommodityInfos的数据。如果用户已对商品进行分类查询,即已单击分类列表的某个分类,比如单击网页的“进口奶粉”,然后再单击“价格”排序,那么网站将会查询模型CommodityInfos的字段types等于“进口奶粉”的数据并以价格从高到低进行排序。

(3)商品列表是展示当前的商品信息,默认情况下是显示整个网站的商品信息,以“销量”从高到低进行排序。商品信息设置了分页功能,每一页只显示6条商品信息,当单击分页导航栏的某个分页时,网站将会根据当前的商品排序方式选择对应的商品信息,比如当前商品列表有18条商品信息,并且以销量进行排序,那么第一页应显示销量第1到第6的商品信息,第二页应显示销量第7到第12的商品信息……以此类推。

​ 除此之外,当我们在顶部的商品搜索功能输入某个关键字并单击查询按钮的时候,网站将关键字与模型CommodityInfos的字段name进行匹配,符合条件的商品信息展示在商品列表页,这些数据还可以选择分类显示、排序设置和分页查询。

​ 综合上述,商品列表页需要实现商品关键字查询、商品分类筛选、商品排序设置和分页显示,这四种查询方式可以任意组合并且互不干扰。数据查询适合使用HTTP的GET请求实现,因此,我们为这四种查询方式分别设置请求参数n、t、s和p。由于项目应用commodity的urls.py已定义路由commodity,所以在PyCharm打开项目应用commodity的views.py定义视图函数commodityView,代码如下:

视图函数commodityView定义了多个变量,其中变量title和classContent是对应模板base.html的模板变量title和classContent,网页效果如图7-2所示。

变量firsts和typesList是查询模型Type的数据,前者是对字段firsts去重查询,获取所有商品的一级分类,后者是查询模型Type的所有数据,它们将显示在网页列表页的分类列表。变量n、t、s和p是获取请求参数n、t、s和p的参数值,只要某个变量的值不为空,该变量将作为变量commodityInfos的查询条件,每个变量的查询说明如下:

(1)变量n是商品搜索功能的关键字,它与模型CommodityInfos的字段name进行模糊匹配,因此查询条件为name__contains=n。

(2)变量t是查询某个分页的商品信息,它以整型格式表示,代表模型Type的主键id,因此程序首先查询模型Type的字段id等于t的数据A,然后从数据A中获取字段seconds的数据B,最后查询模型CommodityInfos等于数据B的数据,从而得到某个分页的商品信息。

(3)变量s是设置商品的排序方式,如果请求参数s为空,则默认变量s等于字符串sold,而字符串sold代表模型CommodityInfos的字段sold,因此请求参数s的值为sold、price、created和likes,分别对应模型CommodityInfos的字段sold、price、created和likes。

(4)变量p是设置商品信息的页数,默认变量p等于1,代表当前第一页的商品信息,即当前排序的第1到第6的商品信息。

​ 变量commodityInfos是模型CommodityInfos的查询对象,通过判断变量n、t和s是否为空,从而决定变量commodityInfos是否添加相应的查询条件,每执行一次查询条件,查询结果重新赋值给变量commodityInfos,覆盖上一次的查询结果,从而使变量n、t和s对应的查询结果能够相互兼容。

​ 当程序得到最终的查询结果(即变量commodityInfos),然后对变量commodityInfos进行分页处理,数据分页由Django内置分页功能完成,其中Paginator(commodityInfos, 6)的6代表每一页的数据量,即每页显示6条商品信息。如果参数p的数值不为整数,则默认返回第一页的商品信息;如果参数p的数值大于分页后的总页数,则默认返回最后一页的商品信息。

分页功能的机制和原理

​ Django已为开发者提供了内置的分页功能,开发者无须自己实现数据分页功能,只需调用Django内置分页功能的函数即可实现。实现数据的分页功能需要考虑多方面的因素,分别说明如下:当前用户访问的页数是否存在上(下)一页。访问的页数是否超出页数上限。数据如何按页截取,如何设置每页的数据量。对于上述考虑因素,Django内置的分页功能已提供解决方法,而且代码的实现方式相对固定,便于开发者理解和使用。分页功能由Paginator类实现,我们在PyCharm里查看该类的定义过程,如图7-3所示。

Paginator类一共定义了4个初始化参数和8个类方法,每个初始化参数和类方法的说明如下:

object_list:必选参数,代表需要进行分页处理的数据,参数值可以为列表、元组或ORM查询的数据对象等。

per_page:必选参数,设置每一页的数据量,参数值必须为整型。

orphans:可选参数,如果最后一页的数据量小于或等于参数orphans的值,就将最后一页的数据合并到前一页的数据。比如有23行数据,若参数per_page=10、orphans=5,则数据分页后的总页数为2,第一页显示10行数据,第二页显示13行数据。

allow_empty_first_page:可选参数,是否允许第一页为空。如果参数值为False并且参数object_list为空列表,就会引发EmptyPage错误。

validate_number():验证当前页数是否大于或等于1。

get_page():调用validate_number()验证当前页数是否有效,函数返回值调用page()。

page():根据当前页数对参数object_list进行切片处理,获取页数所对应的数据信息,函数返回值调用_get_page()

_get_page():调用Page类,并将当前页数和页数所对应的数据信息传递给Page类,创建当前页数的数据对象。count():获取参数object_list的数据长度。num_pages():获取分页后的总页数。page_range():将分页后的总页数生成可循环对象。

_check_object_list_is_ordered():如果参数object_list是ORM查询的数据对象,并且该数据对象的数据是无序排列的,就提示警告信息。

从Paginator类定义的get_page()、page()和_get_page()得知,三者之间存在调用关系,我们将它们的调用关系以流程图的形式表示,如图7-4所示。

​ 从图7-4得知,我们将Paginator类实例化之后,再由实例化对象调用get_page()即可得到Page类的实例化对象。在源码文件paginator.py中可以找到Page类的定义过程,它一共定义了3个初始化参数和7个类方法,每个初始化参数和类方法的说明如下:

object_list:必选参数,代表已切片处理的数据对象。

number:必选参数,代表用户传递的页数。

paginator:必选参数,代表Paginator类的实例化对象。

has_next():判断当前页数是否存在下一页。

has_previous():判断当前页数是否存在上一页。

has_other_pages():判断当前页数是否存在上一页或者下一页。

next_page_number():如果当前页数存在下一页,就输出下一页的页数,否则抛出EmptyPage异常。

previous_page_number():如果当前页数存在上一页,就输出上一页的页数,否则抛出EmptyPage异常。

start_index():输出当前页数的第一行数据在整个数据列表的位置,数据位置从1开始计算。

end_index():输出当前页数的最后一行数据在整个数据列表的位置,数据位置从1开始计算。

测试分页功能

商品列表页的数据渲染

​ 从视图函数commodityView看到,视图函数最终使用模板文件commodity.html作为HTTP响应。在模板文件commodity.html中,我们需要使用变量firsts、typesList、n、t、s、p和pages进行数据渲染和展示,打开模板文件commodity.html,其模板语法如下:

模板文件commodity.html按照功能划分可分为5个部分,在代码中依次标记了①②③④⑤,每个部分的功能说明如下:

(1)标注①首先调用共用模板文件base.html,使base.html和commodity.html产生关联;再使用{% load static %}读取静态资源,然后重写接口content;最后遍历视图函数commodityView定义的变量firsts和typesList,将模型Type的数据生成网页的分类列表,每个二级分类设置了相应的链接,所有链接都是指向商品列表页,只不过每个链接的请求参数t和n各不相同。

(2)标注②设置了商品的排序方式,分别有“销量”、“价格”、“新品”和“收藏”,通过判断变量s来控制每个链接的样式设置,如变量s等于空或者等于sold,那么“销量”样式设为class="active"。每个排序方式设置了相应的链接,所有链接都是指向商品列表页,每个链接的请求参数t、s和n各不相同。

(3)标注③是遍历变量pages的object_list方法生成商品列表,由于变量pages已设置每页的商品显示数量,因此遍历完成后只会显示6条商品信息,每次遍历对象p代表模型CommodityInfos的某行数据,每条商品信息包含了商品详细页的地址链接,以模型CommodityInfos的主键id作为商品详细页的变量id;模型CommodityInfos的字段img调用url方法可生成图片的地址链接;字段name、price和sold分别设置商品的名称、价格和销量数。

(4)标注④是使用变量pages的方法实现分页功能列表,比如判断当前页数是否存在上一页,则可以使用变量pages的has_previous方法判断;获取上一页的页数则使用变量pages的previous_page_number实现。

​ 变量pages调用paginator.page_range方法获取数据分页后的总页数,然后在遍历过程中,每次遍历对象page与pages.number进行对比,pages.number首先使用过滤器add进行自增1或自减1,再与遍历对象page对比,如果判断成功,则生成分页按钮。比如当前页数是第二页,那么分页功能则会生成第一页和第三页的按钮,如图7-5所示。

(5)标注⑤是重写base.html的接口script,该脚本是实现商品分类列表的动态缩放效果。分类列表列举了一级分类和二级分类,单击一级分类前面的符号即可实现二级分类的缩放功能,如图7-6所示。

商品详细页的业务逻辑

​ 商品详细页是整个网站的核心网页之一,所有网页展示的商品信息都设置了商品详细页的地址链接。根据开发需求,商品详细页展示某一商品的主图、名称、规格、数量、详细介绍、购买按钮和收藏按钮,并在商品详细介绍的左侧设置了热销商品列表,如图7-7所示。

从图7-7可以看到,商品详细页分为5个功能区:商品搜索功能、网站导航、商品基本信息、商品详细介绍和热销推荐,每个功能的设计说明如下:

(1)商品基本信息:包含了商品的规格、名称、价格、主图、购买数量、收藏按钮和购买按钮。收藏按钮使用JavaScript脚本完成收藏功能,购买按钮将商品信息和购买数量添加到购物车。

(2)商品详细介绍:以图片形式展示,用于描述商品的细节内容。

(3)热销推荐:在所有商品中(排除当前商品之外)获取并展示前五名销量最高的商品。换句话说,商品基本信息和商品详细介绍皆来自模型CommodityInfos的某条商品信息;热销推荐是查询模型CommodityInfos前五名销量最高的商品(排除当前商品之外);商品收藏则由JavaScript脚本完成。

我们首先实现商品详细页的数据展示,在PyCharm中打开项目应用commodity的views.py定义视图函数detailView,代码如下:

​ 视图函数detailView设置了参数id,因为路由detail设置了路由变量id,相应地,视图函数必须设置相应的函数参数,并且路由变量名称必须与视图函数的参数名称相同,否则程序将提示TypeError异常,如图7-8所示。

​ 如果路由设置了路由变量,而对应的视图函数没有设置相应的函数参数,程序也会提示TypeError异常;如果路由设置了多个路由变量,视图函数应按照路由变量的设置顺序依次添加对应的函数参数。

​ 视图函数detailView定义了变量title、classContent、commoditys和items,其中变量title和classContent将作用于模板文件base.html,而commoditys、items和likes分别在模板文件details.html实现商品展示、热销推荐和收藏按钮的样式设置。

​ 变量items是查询模型CommodityInfos前五名销量最高的商品信息,在查询过程中可以使用exclude将当前商品信息排除。

​ 变量likesList是当前用户与Django的会话连接,即session会话,session是用户在网站的一个身份凭证,而且Session能存储该用户的一些数据信息。

​ 变量likes是判断变量likesList是否含有当前商品的主键id,如果当前商品的主键id已在变量likesList中,那么说明用户已收藏了当前商品。

商品详细页的数据渲染

​ 视图函数detailView使用模板文件details.html作为响应内容,在模板文件details.html中,我们需要使用变量commoditys和items进行数据渲染和展示,打开模板文件details.html,其模板语法如下:

​ 模板文件details.html按照功能划分可分为5个部分,在代码中依次标记了①②③④⑤,每个部分的功能说明如下:(1)标注①是调用模板文件base.html并重写接口content,然后使用模板语法url在“首页”和“所有商品”分别设置路由index和commodity的路由地址。(2)标注②是使用变量commoditys生成商品的基本信息,包括商品主图、名称、规格、原价和折后价。商品购买数量使用JavaScript脚本实现动态增减功能;商品收藏通过判断变量likes来控制按钮的样式设置,如果变量likes为True,说明当前用户已收藏商品,按钮上的星星以实心表示;如果变量likes为False,说明当前用户尚未收藏商品,按钮上的星星以空心表示,如图7-9所示。

(3)标注③是使用变量item生成商品的热销推荐,每个商品只展示商品主图、名称和折后价,商品主图设置了该商品详细页的地址链接,当用户单击商品主图,浏览器即可自动访问该商品详细页。

(4)标注④是使用变量commoditys的字段details的url属性生成商品详细图的地址链接,因为字段details为FileField类型,可以使用url属性来获取图片的地址链接。

(5)标注⑤重写模板文件base.html的接口script,它一共编写了3个JavaScript脚本,每个脚本实现的功能说明如下:

第一个脚本(即layui.config(…))是实现商品购买数量的动态增减功能,在脚本代码中,var cur=$('.number-cont input').val()是获取商品购买数量输入框的数值,而$('.number-cont .btn').on('click',function()是对商品购买数量按钮绑定事件触发函数,$('.number-cont .btn')是定位商品购买数量的增减按钮,如图7-10所示。在这个事件触发函数中,如果单击的按钮对象含有add样式,则认为单击“+”按钮,那么商品购买数量的输入框自增加1;反之则认为单击“-”按钮,程序就判断商品数量是否大于1,若大于1,则在商品购买数量的输入框执行自减1操作。

第二个脚本(即$('.layui-btn.layui-btn-danger.car-btn').on(…))是将“加入购物车”按钮绑定事件触发函数。在脚本中获取商品购买数量(即var quantity = $("#quantity").val()),然后使用模板语法url生成路由shopcart的路由地址,即用户单击“加入购物车”按钮之后,浏览器访问路由shopcart的路由地址,并将商品购买数量quantity和商品主键id作为路由shopcart的请求参数。虽然“加入购物车”按钮设有HTML的标签a,我们还可以在标签a里面设置href属性,但是商品购买数量是动态变化的,如果在标签a里面设置href属性,每次添加或减少商品购买数量,href属性的url地址的请求参数quantity应要随之变化。第三个脚本(即$('#collect').on(…))是对收藏按钮绑定事件触发函数,它是向路由collect发送HTTP的GET请求,并将商品主键id作为请求参数,如果HTTP的响应内容为“收藏成功”,则说明当前商品已被用户收藏,网页的收藏按钮的空心星星转为实心星星,并提示“收藏成功”。

Ajax实现商品收藏

在模板文件details.html中,我们通过重写模板文件base.html的接口script,并对商品收藏按钮绑定了事件触发函数,它是向路由collect发送HTTP的GET请求,这个HTTP请求过程是在JavaScript代码中完成的,这种实现方式称为Ajax请求。Ajax即“Asynchronous Javascript And XML”(异步JavaScript和XML),这是指一种创建交互式、快速动态网页应用的网页开发技术,无须重新加载整个网页的情况下,能够更新部分网页的技术。简单来说,Ajax是向网站的某个路由地址发送HTTP请求(可以是GET请求或POST请求)并获取响应内容,响应内容经过JavaScript处理后再渲染到网页上,从而完成网页内容的局部更新。一般情况下,Ajax请求的响应内容以JSON格式为主。商品收藏按钮是向路由collect发送HTTP的GET请求,因此我们在项目应用commodity的urls.py和views.py定义路由collect及其视图函数collectView,代码如下所示:

视图函数collectView通过读写用户的会话session数据来记录商品的收藏情况,具体的业务逻辑说明如下:

(1)首先从请求对象request获取请求参数id的值,并赋值给变量id,它代表当前商品的主键id;然后设置响应内容result,并以字典格式表示;最后从请求对象request获取会话session数据likes,如果存在数据likes,则赋值给变量likes,否则变量likes设置空列表。

(2)如果变量id不为空,并且变量id不在变量likes里面(变量likes以列表格式表示),那么说明当前商品尚未被当前用户加入收藏,程序将执行商品收藏。

(3)将变量id作为模型CommodityInfos的查询条件,再由查询对象使用update()和F()方法实现字段likes的自增加1操作;然后将响应内容result改为“收藏成功”;最后将当前商品主键id写入会话session数据likes,标记当前商品已被当前用户收藏了。

(4)视图函数返回值使用JsonResponse将变量result作为响应内容,JsonResponse能将Python的字典转换为JSON数据。此外还可以使用HttpResponse方式实现,不过需要自行将字典转换JSON数据,比如HttpResponse(json.dumps(result),content_type='application/json'),首先使用JSON模块转换字典result,然后响应类型content_type要设为application/json。

Session的配置与操作

​ 在视图函数detailView和collectView中,我们通过请求对象request读写会话session数据,在5.2节中,Django接收的HTTP请求信息里带有Cookie信息,Cookie的作用是为了识别当前用户的身份,通过以下例子来说明Cookie的作用。

​ 浏览器向服务器(Django)发送请求,服务器做出响应之后,二者便会断开连接(会话结束),下次用户再来请求服务器,服务器没有办法识别此用户是谁。比如用户登录功能,如果没有Cookie机制支持,那么只能通过查询数据库实现,并且每次刷新页面都要重新操作一次用户登录才可以识别用户,这会给开发人员带来大量的冗余工作,简单的用户登录功能会给服务器带来巨大的负载压力。

​ Cookie是从浏览器向服务器传递数据,让服务器能够识别当前用户,而服务器对Cookie的识别机制是通过Session实现的,Session存储了当前用户的基本信息,如姓名、年龄和性别等。由于Cookie存储在浏览器里面,而且Cookie的数据是由服务器提供的,如果服务器将用户信息直接保存在浏览器中,就很容易泄露用户信息,并且Cookie大小不能超过4KB,不能支持中文,因此需要一种机制在服务器的某个域中存储用户数据,这个域就是Session。

​ 总而言之,Cookie和Session是为了解决HTTP协议无状态的弊端、为了让浏览器和服务端建立长久联系的会话而出现的,两者的关系说明如下:

Session存储在服务器端,Cookie存储在客户端,所以Session的安全性比Cookie高。当获取某用户的Session数据时,首先从用户传递的Cookie里获取sessionid,然后根据sessionid在网站服务器找到相应的Session。Session存放在服务器的内存中,Session的数据不断增加会造成服务器的负担,因此存放在Session中的数据不能过于庞大。

​ 当访问网站时,所有的HTTP请求都经过中间件处理,而中间件SessionMiddleware会判断当前请求的用户身份是否存在,并根据判断结果执行相应的程序处理。中间件SessionMiddleware相当于HTTP请求接收器,根据请求信息做出相应的调度,而程序的执行则由settings.py的配置属性INSTALLED_APPS的django.contrib.sessions完成,其配置信息如图7-12所示。

​ django.contrib.sessions实现了Session的创建和操作处理,如创建或存储用户的Session对象、管理Session的生命周期等。它默认使用数据库存储Session信息,执行数据迁移时,在数据库中可以看到数据表django_session,如图7-13所示

​ SESSION_ENGINE用于配置服务器Session的保存方式,而浏览器的Cookie用于记录数据表django_session的session_key,Session还可以设置相关的配置信息,如生命周期、传输方式和保存路径等,只需在settings.py中添加配置属性即可,说明如下:

SESSION_COOKIE_NAME = "sessionid":浏览器的Cookie以键值对的形式保存数据表django_session的session_key,该配置是设置session_key的键,默认值为sessionid。

SESSION_COOKIE_PATH = "/":设置浏览器的Cookie生效路径,默认值为“/”,即127.0.0.1:8000。SESSION_COOKIE_DOMAIN = None:设置浏览器的Cookie生效域名。SESSION_COOKIE_SECURE = False:设置传输方式,若为False,则使用HTTP,否则使用HTTPS。

SESSION_COOKIE_HTTPONLY = True:是否只能使用HTTP协议传输。SESSION_COOKIE_AGE = 1209600:设置Cookie的有效期,默认时间为两周。

SESSION_COOKIE_NAME = "sessionid":浏览器的Cookie以键值对的形式保存数据表django_session的session_key,该配置是设置session_key的键,默认值为sessionid。

SESSION_COOKIE_PATH = "/":设置浏览器的Cookie生效路径,默认值为“/”,即127.0.0.1:8000。

SESSION_COOKIE_DOMAIN = None:设置浏览器的Cookie生效域名。SESSION_COOKIE_SECURE = False:设置传输方式,若为False,则使用HTTP,否则使用HTTPS。

SESSION_COOKIE_HTTPONLY = True:是否只能使用HTTP协议传输。SESSION_COOKIE_AGE = 1209600:设置Cookie的有效期,默认时间为两周。

​ 了解Session的运行原理和相关配置后,最后讲解Session的读写操作。Session的数据类型可理解为Python的字典类型,主要在视图函数中执行读写操作,并且从用户请求对象中获取,即来自视图函数的参数request。Session的读写如下:

JavaScript的Ajax请求

​ 如果网站开发模式不是采用前后端分离,作为后端开发人员必须灵活掌握Ajax请求,因为在开发过程中,前端开发人员不懂Django的开发原理,在这种开发环境下编写Ajax请求还不如后端开发人员自行编写较为方便,这样能省去沟通协调的时间,从而提高开发效率。Ajax请求主要有GET和POST请求,GET请求主要用于数据查询;POST请求主要实现网站数据的增删改操作。本节讲述如何使用原生JavaScript编写Ajax请求,原生JavaScript编写Ajax请求的代码如下:

从上述代码看到,原生JavaScript的Ajax请求在实现GET和POST请求过程存在相似之处,具体的实现过程如下:

(1)使用XMLHttpRequest创建实例化对象xhr,再由实例化对象xhr调用open()方法设置Ajax请求的请求方式。

(2)open()方法设有3个参数,其语法格式为:open(method, url, async)。参数method为HTTP的请求方式,比如发送GET请求,则设为字符串GET,发送POST请求则设为字符串POST;参数url为HTTP的请求地址,即网站定义的路由地址;参数async表示是否为异步请求,默认值为true,所有HTTP请求均为异步请求。如果需要发送同步请求,将此参数设置为false即可,但是同步请求将锁住浏览器,用户的其他操作必须等待HTTP请求完成才可以执行。

(3)设置了Ajax的请求方式,下一步可以使用send()方法执行Ajax请求。send()方法设有参数string,如果是发送GET请求,则无须设置参数string,GET请求的请求参数只能在url设置,即open()方法的参数url;如果是发送POST请求,那么参数string必须为JSON字符串格式,比如JSON数据为data = {"name":"Django"},参数string应写为"name=Django",或者使用JSON.stringify(data)转换为JSON字符串格式。

(3)设置了Ajax的请求方式,下一步可以使用send()方法执行Ajax请求。send()方法设有参数string,如果是发送GET请求,则无须设置参数string,GET请求的请求参数只能在url设置,即open()方法的参数url;如果是发送POST请求,那么参数string必须为JSON字符串格式,比如JSON数据为data = {"name":"Django"},参数string应写为"name=Django",或者使用JSON.stringify(data)转换为JSON字符串格式。

(4)如果网站的路由地址设置了特殊的请求方式,比如请求头设有特殊参数,我们还可以使用实例化对象xhr调用setRequestHeader()方法设置请求头。每调用一次setRequestHeader()只能设置请求头的某个参数,例如设置参数User-Agent和Content-type,实例化对象xhr需调用两次setRequestHeader()方法,详细的设置方式如下:

(5)使用send()方法执行Ajax请求之后,我们还需要调用onreadystatechange()方法监听整个Ajax请求过程。在监听过程中,实例化对象xhr从readyState属性获取请求状态,如果请求状态等于4,则说明Ajax请求与网站的路由地址通信成功;与此同时,实例化对象xhr从status属性获取响应状态,如果响应状态等于200,说明Ajax请求已得到网站的响应,那么实例化对象xhr可以从responseText属性获取网站的响应内容,从而完成一次Ajax请求。

jQuery的Ajax请求

​ 由于原生JavaScript的Ajax请求需要编写较多代码,因此jQuery在此基础上进行了简化,开发人员只需数行代码即可实现Ajax请求。

​ jQuery是一个快速、简洁的JavaScript框架,其设计的宗旨是“Write Less,Do More”,即倡导写更少的代码,做更多的事情。它封装JavaScript常用的功能代码,提供一种简便的JavaScript设计模式,优化HTML文档操作、事件处理、动画设计和Ajax交互。

​ jQuery编写Ajax请求的代码如下:

​ jQuery通过定义ajax()函数实现Ajax请求,并且通过多个函数参数来设置请求方式,具体每个函数参数的说明如表7-1所示。

​ 除了jQuery的ajax()函数能实现HTTP的GET和POST请求之外,jQuery还定义了get()和post()函数,它们也可以实现HTTP的GET和POST请求,详细的函数语法如下:

从jQuery定义get()和post()函数看到,它们比ajax()函数更为简化,函数参数相对较少,在使用方式上更加便捷。如果网站定义的API接口(即网站为Ajax定义的路由地址)没有特殊要求,一般情况下使用get()和post()函数完成Ajax请求即可,具体的使用方法如下: