Ajax(Asynchronous Javascript And XML:异步 JavaScript 和 XML),是指一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
使用Ajax的最大优点,就是能在不更新整个页面的前提下维护数据。这使得Web应用程序更为迅捷地回应用户动作,并避免了在网络上发送那些没有改变的信息。
但是Ajax可能破坏浏览器的后退与加入收藏书签功能。在动态更新页面的情况下,用户无法回到前一个页面状态,这是因为浏览器仅能记下历史记录中的静态页面。
Ajax的定义
Ajax有最初是由js编写的,后来随着js框架的发展,jq,vue等大型框架都对ajax进行了封装,在这里我们学习两种ajax的编写。
Js ajax
我们看一个简单的ajax案例
首先我们创建如图所示的一个项目:
代码如下:
# app01/views.py
from django.http import JsonResponse
from django.shortcuts import render
# Create your views here.
def getPage(request):
'''返回页面'''
return render(request,'django_ajax_pro.html')
def sendData(request):
'''
响应ajax请求,在这里要注意响应的内容是json对象
'''
return JsonResponse({"data":"hello world"})
#django_pro5/urls
from django.conf.urls import include, url
from django.contrib import admin
from app01.views import getPage, sendData
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^ckeditor/',include('ckeditor_uploader.urls')),
url(r'ajaxPro/',getPage),
url(r'ajaxData/',sendData),
]
ajax_js_example
效果如下:
在这里我们关注上面的代码的几个点
1、在视图当中我们定义了两个函数,这里大家一定要搞明白,ajax是局部提交,首先我们需要有页面承载我们的前端效果,其次在前端发起ajax请求,进行响应的是一个独立的视图,并不是我们承载前端的视图。
2、ajax通常返回的数据是json数据,在老版本的Django当中需要先导入json模块,然后用HTTPRespose进行返回,在新版本django.http下已经封装好了一个叫做JsonResponse的功能,他返回的就是json数据
3、js 编写 ajax 的变化有很多种,但是一定注意他的必要的步骤,我们把刚才的代码拆开看一下
1. 构建XMLHttpRequest对象
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); //Msxml2版本Microsoft浏览器
}catch (e){
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");//Microsoft版本Microsoft浏览器
}catch (e1){
xmlhttp = new XMLHttpRequest();//非Microsoft浏览器,如:谷歌、Firefox等
}
}
2. 发起请求
function getData() {
url = "/ajaxData/";
xmlhttp.open("GET",url,true);
xmlhttp.onreadystatechange = updatePage;
xmlhttp.send(null)
}
3. 进行回调,响应函数
function updatePage() {
console.log("+++++++++++++++++++++++++++++++++");
console.log(xmlhttp.readyState);
console.log(xmlhttp.status);
console.log("+++++++++++++++++++++++++++++++++");
if (xmlhttp.readyState == 4 && xmlhttp.status == 200){
var response = xmlhttp.responseText;//返回响应的内容
console.log(response)
}
}
在掌握了上面的例子之后,我们来解释一些需要记住的常识
Ajax对象readyState的五种状态
状态编号 |
状态 |
描述 |
0 |
未初始化 |
(XMLHttpRequest)对象已经创建,但还没有调用open()方法。值为0表示对象已经存在,否则浏览器会报错:对象不存在。 |
1 |
载入/正在发送请求 |
对XMLHttpRequest对象进行初始化,即调用open()方法,根据参数(method,url,true),完成对象状态的设置。并调用send()方法开始向服务端发送请求。值为1表示正在向服务端发送请求。 |
2 |
载入完成/数据接收 |
此阶段接收服务器端的响应数据。但获得的还只是服务端响应的原始数据,并不能直接在客户端使用。值为2表示send()方法执行完成,已经接收完全部响应数据。并为下一阶段对数据解析作好准备。 |
3 |
交互/解析数据 |
此阶段解析接收到的服务器端响应数据。即根据服务器端响应头部返回的MIME类型把数据转换成能通过responseBody、responseText或responseXML属性存取的格式,为在客户端调用作好准备。值为3表示正在解析数据。 |
4 |
后台处理完成 |
此阶段确认全部数据都已经解析为客户端可用的格式,解析已经完成。值为4表示数据解析完毕,可以通过XMLHttpRequest对象的相应属性取得数据。 |
Ajax对象status状态码(web request 请求响应码)
200:请求成功(后台处理结果ok) |
|
状态码 |
描述 |
200 |
服务器已成功处理了请求。通常,这表示服务器提供了请求的网页。 |
201 |
请求成功且服务器已创建了新的资源。 |
202 |
服务器已接受了请求,但尚未对其进行处理。 |
203 |
服务器已成功处理了请求,但返回了可能来自另一来源的信息。 |
204 |
服务器成功处理了请求,但未返回任何内容。 |
205 |
服务器成功处理了请求,但未返回任何内容(与 204 响应不同,此响应要求请求者重置文档视图(例如清除表单内容以输入新内容)。) |
206 |
服务器成功处理了部分 GET 请求。 |
303:重定向 |
|
状态码 |
描述 |
300 |
服务器根据请求可执行多种操作。 |
301 |
请求的网页已被永久移动到新位置。服务器返回此响应时,会自动将请求者转到新位置。 |
302 |
服务器目前正从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。 |
303 |
当请求者应对不同的位置进行单独的 GET 请求以检索响应时,服务器会返回此代码。 |
304 |
自从上次请求后,请求的网页未被修改过。服务器返回此响应时,不会返回网页内容。 |
305 |
请求者只能使用代理访问请求的网页。 |
307 |
服务器目前正从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。 |
400:请求错误 |
|
状态码 |
描述 |
400 |
服务器不理解请求的语法。 |
401 |
此页要求授权。您可能不希望将此网页纳入索引。 |
403 |
服务器拒绝请求。 |
404 |
服务器找不到请求的网页。例如,对于服务器上不存在的网页经常会返回此代码。 |
405 |
禁用请求中指定的方法。 |
406 |
无法使用请求的内容特性响应请求的网页。 |
407 |
此状态码与 401 类似,但指定请求者必须授权使用代理。如果服务器返回此响应,还表示请求者应当使用代理。 |
408 |
服务器等候请求时发生超时。 |
409 |
服务器在完成请求时发生冲突。服务器必须在响应中包含有关冲突的信息。 |
410 |
请求的资源永久删除后,服务器返回此响应。 |
411 |
服务器不接受不含有效内容长度标头字段的请求。 |
412 |
服务器未满足请求者在请求中设置的其中一个前提条件。 |
413 |
服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。 |
414 |
请求的 URI(通常为网址)过长,服务器无法处理。 |
415 |
请求的格式不受请求页面的支持。 |
416 |
如果页面无法提供请求的范围,则服务器会返回此状态码。 |
417 |
服务器未满足"期望"请求标头字段的要求。 |
500:服务器错误 |
|
状态码 |
描述 |
500 |
服务器遇到错误,无法完成请求。 |
501 |
服务器不具备完成请求的功能。 |
502 |
服务器作为网关或代理,从上游服务器收到了无效的响应。 |
503 |
目前无法使用服务器(由于超载或进行停机维护)。通常,这只是一种暂时的状态。 |
504 |
服务器作为网关或代理,未及时从上游服务器接收请求。 |
505 |
服务器不支持请求中所使用的 HTTP 协议版本。 |
上面是js ajax get最简单的案例,接下来看一个完整的js ajax的请求案例,我们以后端校验用户名是否重复为例。
首先我们先定义一个列表作为用户池,用来存放已经存在的用户名,当然,在工作当中我们是有数据库存放用户信息的。然后开始编写接收数据之后进行比对的逻辑,返回的参数。
views视图函数:
def userValidPage(request):
return render(request,'ajax_js_example.html')
def userValid(request):
'''响应ajax请求'''
userList = ["if","for","while","and","or","linux","python","django"]
result = {"state":"error","data":""}
if request.method == "GET" and request.GET:
request_name = request.GET.get("username")
if request_name:
if request_name in userList:
result["data"] = "用户名已存在"
else:
result["state"] = "success"
result["data"] = "用户名可以使用"
else:
result["data"] = "请输入用户名!"
else:
result["state"] = "error"
result["data"] = "我们只是接受get请求"
return JsonResponse(result)
url路由设置:
from django.conf.urls import include, url
from django.contrib import admin
from app01.views import getPage, sendData, userValidPage,userValid
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^ckeditor/',include('ckeditor_uploader.urls')),
url(r'ajaxPro/',getPage),
url(r'ajaxData/',sendData),
url(r'^ajax_page/',userValidPage),
url(r'^ajax_data/',userValid),
]
template前端页面:
Title
在这里有个问题大家要注意。Js ajax返回的数据是一个字符串,我们需要将他强行转换为json格式,所以使用evel方法进行了转换
var response = xmlhttp.responseText;
var data = eval('('+response+')');
这样写的原因在于:eval本身的问题。 由于json是以”{}”的方式来开始以及结束的,在JS中,它会被当成一个语句块来处理,所以必须强制性的将它转换成一种表达式。
加上圆括号的目的是迫使eval函数在处理JavaScript代码的时候强制将括号内的表达式(expression)转化为对象,而不是作为语句(statement)来执行。举一个例子,例如对象子变量{},如若不加外层的括号,那么eval会将大括号识别为JavaScript代码块的开始和结束标记,那么{}将会被认为是执行了一句空语句。所以下面两个执行结果是不同的:
alert(eval("{}"); // return undefined
alert(eval("({})");// return object[Object]
我们执行的效果如下:
Jq ajax
上面我们讲了js的ajax请求,下面来看一下jq的ajax 请求。相对于js的ajax get请求,jq的编写更加简单。
还是上面的例子,我们用jq实现一下,后端ajax数据校验视图代码我们不用动。
views视图增加一个承载页面:
def jqValidPage(request):
return render(request,'ajax_jq_example.html')
然后将jq文件方法static目录,(当然在这里是要配置Django的静态目录的)
Settings静态目录配置
STATICFILES_DIRS = (
os.path.join(BASE_DIR,"static"),
)
路由指出也不要忘了
from django.conf.urls import include, url
from django.contrib import admin
from app01.views import getPage, sendData, userValidPage,userValid,jqValidPage
urlpatterns = [
url(r'^ajax_jq_page',jqValidPage),
]
接下来我们来编写前端的jq请求:
Title
效果如下:
从上面的方法看出,在实现相同功能的情况下,jQuery的代码要JavaScript的代码简洁很多
Ajax常用的配置参数给大家展示一下
参数名称 |
参数类型 |
参数描述 |
async |
Boolean |
默认设置下,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为 false。 |
beforeSend |
Function |
发送请求前可修改 XMLHttpRequest 对象的函数,如添加自定义 HTTP 头。 |
cache |
Boolean |
true,dataType 为 script 和 jsonp 时默认为 false。设置为 false 将不缓存此页面。 |
contentType |
String |
"application/x-www-form-urlencoded"。发送信息至服务器时内容编码类型。 |
context |
Object |
这个对象用于设置 Ajax 相关回调函数的上下文。也就是说,让回调函数内 this 指向这个对象(如果不设定这个参数,那么 this 就指向调用本次 AJAX 请求时传递的 options 参数)。比如指定一个 DOM 元素作为 context 参数,这样就设置了 success 回调函数的上下文为这个 DOM 元素。 |
data |
String |
发送到服务器的数据。将自动转换为请求字符串格式。GET 请求中将附加在 URL 后。查看 processData 选项说明以禁止此自动转换。必须为 Key/Value 格式。如果为数组,jQuery 将自动为不同值对应同一个名称。如 {foo:["bar1", "bar2"]} 转换为 '&foo=bar1&foo=bar2'。 |
dataFilter |
Function |
给 Ajax 返回的原始数据的进行预处理的函数。提供 data 和 type 两个参数:data 是 Ajax 返回的原始数据,type 是调用 jQuery.ajax 时提供的 dataType 参数。函数返回的值将由 jQuery 进一步处理。 |
dataType |
String |
预期服务器返回的数据类型。如果不指定,jQuery 将自动根据 HTTP 包 MIME 信息来智能判断,比如 XML MIME 类型就被识别为 XML。在 1.4 中,JSON 就会生成一个 JavaScript 对象,而 script 则会执行这个脚本。随后服务器端返回的数据会根据这个值解析后,传递给回调函数。 |
error |
Function |
自动判断 (xml 或 html)。 |
global |
Boolean |
是否触发全局 AJAX 事件。 |
ifModified |
Boolean |
仅在服务器数据改变时获取新数据。 |
jsonp |
String |
在一个 jsonp 请求中重写回调函数的名字。 |
jsonpCallback |
String |
为 jsonp 请求指定一个回调函数名。 |
password |
String |
用于响应 HTTP 访问认证请求的密码 |
success |
Function |
请求成功后的回调函数。 |
timeout |
Number |
设置请求超时时间(毫秒)。此设置将覆盖全局设置。 |
type |
String |
默认值: "GET")。请求方式 ("POST" 或 "GET"), 默认为 "GET"。 |
url |
String |
默认当前页地址。发送请求的地址。 |
以上就是ajax的GET方法下的js以及jq,后期我会再给大家带来ajax的POST方法