目录:
一、JSON
学习Ajax前,先学习js的JSON.
1.1 什么是JSON?
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。JSON是用字符串来表示Javascript对象;
请大家记住一句话:json字符串就是js对象的一种表现形式(字符串的形式)
import json
i=10
s=\'hello\'
t=(1,4,6)
l=[3,5,7]
d={\'name\':"yuan"}
json_str1=json.dumps(i)
json_str2=json.dumps(s)
json_str3=json.dumps(t)
json_str4=json.dumps(l)
json_str5=json.dumps(d)
print(json_str1) #\'10\'
print(json_str2) #\'"hello"\'
print(json_str3) #\'[1, 4, 6]\'
print(json_str4) #\'[3, 5, 7]\'
print(json_str5) #\'{"name": "yuan"}\'
这里面的json_str就是json字符串;
那么json字符串里都可以放哪些值呢?
JSON字符串内的值:
- 数字 (整数或浮点数)
- 字符串 (在双引号中)
- 逻辑值 (true 或 false)
- 数组 (在方括号中)
- 对象 (在花括号中,引号用双引)
- null
前端接受到json字符串,就可以通过JSON.parse()等方法解析成json对象(即js对象)直接使用了。
1.2 python与json对象的对应:
python --> json dict object list,tuple array str,unicode string int,long,float number True true False false None null
让我们看一个带方法的json对象:
var person = {"name":"alex",
"sex":"men",
"teacher":{
"name":"tiechui",
"sex":"half_men",
},
"bobby":[\'basketball\',\'running\'],
"getName":function() {return 80;}
};
alert(person.name);
alert(person.getName());
alert(person.teacher.name);
alert(person.bobby[0]);
person是一个json对象,因为它满足json规范。
1.3 .parse()和.stringify()
parse() 用于从一个json字符串中解析出json对象,如 var str = \'{"name":"yuan","age":"23"}\' 结果:JSON.parse(str) ------> Object {age: "23",name: "yuan"} stringify()用于从一个json对象解析成json字符串,如 var c= {a:1,b:2} 结果: JSON.stringify(c) ------> \'{"a":1,"b":2}\' 注意1:单引号写在{}外,每个属性名都必须用双引号,否则会抛出异常。 a={name:"yuan"}; //ok b={\'name\':\'yuan\'}; //ok c={"name":"yuan"}; //ok alert(a.name); //ok alert(a[name]); //undefined alert(a[\'name\']) //ok
1.4 django向js发送数据
def login(request):
obj={\'name\':"alex111"}
return render(request,\'index.html\',{"objs":json.dumps(obj)})
#----------------------------------
<script>
var temp={{ objs|safe }}
alert(temp.name);
alert(temp[\'name\'])
</script>
*这里需要注意的是从python传递到html页面的是一个包含有json的对象,因此需要加上 safe过滤器
二、什么是AJAX
AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)。
- 同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
- 异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。
AJAX除了异步的特点外,还有一个就是:浏览器页面局部刷新;(这一特点给用户的感受是在不知不觉中完成请求和响应过程);
利用JS实现一个时钟,也就是使用了AJAX技术;
利用Ajax实现用户名为空检测:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ajax</title>
</head>
<body>
<div>
<div><h2>注册页面</h2></div>
<div>
<form action="" method="post" id="form1">
<div>username: <input type="text" name="username" id="username"></div>
<span id="usernameSpan"></span>
<div>password: <input type="password" name="password"></div>
<span id="passwordSpan"></span>
<div><input type="submit" value="submit"></div>
</form>
</div>
</div>
</body>
<script>
window.onload = function () {
var form=document.getElementById("form1");
form.onsubmit=function () {
var usernameValue=form.username.value;
if(!usernameValue){
var usernameSpan=document.getElementById("usernameSpan");
usernameSpan.innerText = "用户名不能为空!";
return false;
}
return true;
};
// var username=document.getElementById("username");
// username.onblur=function () {
// var usernameValue=form.username.value;
// if(!usernameValue){
// var usernameSpan=document.getElementById("usernameSpan");
// usernameSpan.innerText = "用户名不能为空!";
// return false;
// }
// return true;
}
};
</script>
</html>
当我们点击提交按钮的时候,JS就会进行执行:
三 、 AJAX常见应用情景
当我们在百度中输入一个“老”字后,会马上出现一个下拉列表!列表中显示的是包含“传”字的4个关键字。
其实这里就使用了AJAX技术!当文件框发生了输入变化时,浏览器会使用AJAX技术向服务器发送一个请求,查询包含“传”字的前10个关键字,然后服务器会把查询到的结果响应给浏览器,最后浏览器把这4个关键字显示在下拉列表中。
- 整个过程中页面没有刷新,只是刷新页面中的局部位置而已!
- 当请求发出后,浏览器还可以进行其他操作,无需等待服务器的响应!
当输入用户名后,把光标移动到其他表单项上时,浏览器会使用AJAX技术向服务器发出请求,服务器会查询名为zhangSan的用户是否存在,最终服务器返回true表示名为lemontree7777777的用户已经存在了,浏览器在得到结果后显示“用户名已被注册!”。
- 整个过程中页面没有刷新,只是局部刷新了;
- 在请求发出后,浏览器不用等待服务器响应结果就可以进行其他操作;
四、AJAX的优缺点
优点:
- AJAX使用Javascript技术向服务器发送异步请求;
- AJAX无须刷新整个页面;
- 因为服务器响应内容不再是整个页面,而是页面中的局部,所以AJAX性能高;
缺点:
- AJAX并不适合所有场景,很多时候还是要使用同步交互;
- AJAX虽然提高了用户体验,但无形中向服务器发送的请求次数增多了,导致服务器压力增大;
- 因为AJAX是在浏览器中使用Javascript技术完成的,所以还需要处理浏览器兼容性问题;
五、XMLHttpRequest
什么是 XMLHttpRequest 对象?
XMLHttpRequest 对象用于在后台与服务器交换数据。
XMLHttpRequest 对象是开发者的梦想,因为您能够:
- 在不重新加载页面的情况下更新网页
- 在页面已加载后从服务器请求数据
- 在页面已加载后从服务器接收数据
- 在后台向服务器发送数据
所有现代的浏览器都支持 XMLHttpRequest 对象。
六、AJAX技术与实现
四步操作:
- 创建核心对象;
- 使用核心对象打开与服务器的连接;
- 发送请求
- 注册监听,监听服务器响应。
XMLHTTPRequest
- open(请求方式, URL, 是否异步)
- send(请求体)
- onreadystatechange,指定监听函数,它会在xmlHttp对象的状态发生变化时被调用
- readyState,当前xmlHttp对象的状态,其中4状态表示服务器响应结束
- status:服务器响应的状态码,只有服务器响应结束时才有这个东东,200表示响应成功;
- responseText:获取服务器的响应体
AJAX实现
后端代码:
ef login(request):
print(\'hello ajax\')
return render(request,\'index.html\')
def ajax_get(request):
return HttpResponse(\'helloyuanhao\')
AJAX核心(XMLHttpRequest):
其实AJAX就是在Javascript中多添加了一个对象:XMLHttpRequest对象。所有的异步交互都是使用XMLHttpServlet对象完成的。也就是说,我们只需要学习一个Javascript的新对象即可;
var xmlHttp = new XMLHttpRequest();(大多数浏览器都支持DOM2规范)
打开与服务器的连接(open方法):
当得到XMLHttpRequest对象后,就可以调用该对象的open()方法打开与服务器的连接了。open()方法的参数如下:
open(method, url, async):
- method:请求方式,通常为GET或POST;
- url:请求的服务器地址,例如:/ajaxdemo1/AServlet,若为GET请求,还可以在URL后追加参数;
- async:这个参数可以不给,默认值为true,表示异步请求;
var xmlHttp = createXMLHttpRequest();
xmlHttp.open("GET", "/ajax_get/", true);
发送请求
当使用open打开连接后,就可以调用XMLHttpRequest对象的send()方法发送请求了。send()方法的参数为POST请求参数,即对应HTTP协议的请求体内容,若是GET请求,需要在URL后连接参数。
注意:若没有参数,需要给出null为参数!若不给出null为参数,可能会导致FireFox浏览器不能正常发送请求!
xmlHttp.send(null);
接收服务器响应
当请求发送出去后,服务器端Servlet(是用Java编写的服务器端程序)就开始执行了,但服务器端的响应还没有接收到。接下来我们来接收服务器的响应。
XMLHttpRequest对象有一个onreadystatechange事件,它会在XMLHttpRequest对象的状态发生变化时被调用。下面介绍一下XMLHttpRequest对象的5种状态:
- 0:初始化未完成状态,只是创建了XMLHttpRequest对象,还未调用open()方法;
- 1:请求已开始,open()方法已调用,但还没调用send()方法;
- 2:请求发送完成状态,send()方法已调用;
- 3:开始读取服务器响应;
- 4:读取服务器响应结束。
onreadystatechange事件会在状态为1、2、3、4时引发。
下面代码会被执行四次!对应XMLHttpRequest的四种状态!
xmlHttp.onreadystatechange = function() {
alert(\'hello\');
};
但通常我们只关心最后一种状态,即读取服务器响应结束时,客户端才会做出改变。我们可以通过XMLHttpRequest对象的readyState属性来得到XMLHttpRequest对象的状态。
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState == 4) {
alert(\'hello\');
}
};
其实我们还要关心服务器响应的状态码是否为200,其服务器响应为404,或500,那么就表示请求失败了。我们可以通过XMLHttpRequest对象的status属性得到服务器的状态码。
最后,我们还需要获取到服务器响应的内容,可以通过XMLHttpRequest对象的responseText得到服务器响应内容。
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
alert(xmlHttp.responseText);
}
};
if 发送POST请求:
<1>需要设置请求头:xmlHttp.setRequestHeader(“Content-Type”, “application/x-www-form-urlencoded”);
注意 :form表单会默认这个键值对;不设定,Web服务器会忽略请求体的内容。
<2>在发送时可以指定请求体了:xmlHttp.send(“username=yuan&password=123”)
AJAX实现小结:
创建XMLHttpRequest对象; 调用open()方法打开与服务器的连接; 调用send()方法发送请求; 为XMLHttpRequest对象指定onreadystatechange事件函数,这个函数会在 XMLHttpRequest的1、2、3、4,四种状态时被调用; XMLHttpRequest对象的5种状态,通常我们只关心4状态。 XMLHttpRequest对象的status属性表示服务器状态码,它只有在readyState为4时才 能获取到。 XMLHttpRequest对象的responseText属性表示服务器响应内容,它只有在 readyState为4时才能获取到!
请求完整代码:
<h1>AJAX</h1>
<button onclick="send()">测试</button>
<div id="div1"></div>
<script>
function createXMLHttpRequest() {
try {
return new XMLHttpRequest();//大多数浏览器
} catch (e) {
try {
return new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
return new ActiveXObject("Microsoft.XMLHTTP");
}
}
}
function send() {
var xmlHttp = createXMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
var div = document.getElementById("div1");
div.innerText = xmlHttp.responseText;
div.textContent = xmlHttp.responseText;
}
};
xmlHttp.open("POST", "/ajax_post/", true);
//post: xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlHttp.send(null); //post: xmlHttp.send("b=B");
}
</script>
#--------------------------------views.py
from django.views.decorators.csrf import csrf_exempt
def login(request):
print(\'hello ajax\')
return render(request,\'index.html\')
@csrf_exempt #csrf防御
def ajax_post(request):
print(\'ok\')
return HttpResponse(\'helloyuanhao\')
七、AJAX实例(用户名是否已被注册)
1 功能介绍
在注册表单中,当用户填写了用户名后,把光标移开后,会自动向服务器发送异步请求。服务器返回true或false,返回true表示这个用户名已经被注册过,返回false表示没有注册过。
客户端得到服务器返回的结果后,确定是否在用户名文本框后显示“用户名已被注册”的错误信息!
2 案例分析
- 页面中给出注册表单;
- 在username表单字段中添加onblur事件,调用send()方法;
- send()方法获取username表单字段的内容,向服务器发送异步请求,参数为username;
- django 的视图函数:获取username参数,判断是否为“yuan”,如果是响应true,否则响应false
3 代码实现
<script type="text/javascript">
function createXMLHttpRequest() {
try {
return new XMLHttpRequest();
} catch (e) {
try {
return new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
return new ActiveXObject("Microsoft.XMLHTTP");
}
}
}
function send() {
var xmlHttp = createXMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
if(xmlHttp.responseText == "true") {
document.getElementById("error").innerText = "用户名已被注册!";
document.getElementById("error").textContent = "用户名已被注册!";
} else {
document.getElementById("error").innerText = "";
document.getElementById("error").textContent = "";
}
}
};
xmlHttp.open("POST", "/ajax_check/", true, "json");
xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
var username = document.getElementById("username").value;
xmlHttp.send("username=" + username);
}
</script>
//--------------------------------------------------index.html
<h1>注册</h1>
<form action="" method="post">
用户名:<input id="username" type="text" name="username" onblur="send()"/><span id="error"></span><br/>
密 码:<input type="text" name="password"/><br/>
<input type="submit" value="注册"/>
</form>
//--------------------------------------------------views.py
from django.views.decorators.csrf import csrf_exempt
def login(request):
print(\'hello ajax\')
return render(request,\'index.html\')
# return HttpResponse(\'helloyuanhao\')
@csrf_exempt
def ajax_check(request):
print(\'ok\')
username=request.POST.get(\'username\',None)
if username==\'yuan\':
return HttpResponse(\'true\')
return HttpResponse(\'false\')
八、jQuery实现的ajax
1 核心API的基本使用:
<1> $.ajax的两种写法: $.ajax("url",{}) $.ajax({}) <2> $.ajax的基本使用 $.ajax({ url:"//", data:{a:1,b:2}, type:"GET", success:function(){} }) <3> 回调函数 $.ajax(\'/user/allusers\', { success: function (data) { console.log(arguments); }, error: function (jqXHR, textStatus, err) { // jqXHR: jQuery增强的xhr // textStatus: 请求完成状态 // err: 底层通过throw抛出的异常对象,值与错误类型有关 console.log(arguments); }, complete: function (jqXHR, textStatus) { // jqXHR: jQuery增强的xhr // textStatus: 请求完成状态 success | error console.log(\'statusCode: %d, statusText: %s\', jqXHR.status, jqXHR.statusText); console.log(\'textStatus: %s\', textStatus); }, statusCode: { \'403\': function (jqXHR, textStatus, err) { console.log(arguments); //注意:后端模拟errror方式:HttpResponse.status_code=500 }, \'400\': function () { } } });
2 实例代码
表单验证:
<!DOCTYPE html>
{% load staticfiles %}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ajax</title>
</head>
<body>
<div>
<form id="formadd">
<label for="id_name">用户名</label>
<input type="text" id="id_name"/>
<label for = "id_password">密码</label>
<input type="password" id="id_password"/>
<button type="submit" id="submit" >提交</button>
</form>
</div>
</body>
<script src="{% static "js/jquery.js" %}"></script>
<script>
$("#formadd").submit(function(){
$.ajaxSetup({
data: {csrfmiddlewaretoken: \'{{ csrf_token }}\' }
});
$.ajax({
type:"POST",
data:{username:$("#id_name").val()},
url:"{% url "index" %}",
cache:false,
dataType:"html",
success:function (result) {
alert(result);
},
error:function (result) {
alert(result);
}
});
return false;
});
</script>
</html>
input验证:
<!DOCTYPE html>
{% load staticfiles %}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ajax</title>
</head>
<body>
<div>
<form id="formadd">
<label for="id_name">用户名</label>
<input type="text" id="id_name"/> <span id="span1"></span>
<label for = "id_password">密码</label>
<input type="password" id="id_password"/>
<button type="submit" id="submit" >提交</button>
</form>
</div>
</body>
<script src="{% static "js/jquery.js" %}"></script>
<script>
$("#id_name").blur(function () {
$.ajaxSetup({
data: {csrfmiddlewaretoken: \'{{ csrf_token }}\'}
});
$.ajax({
type:"POST",
data:{username:$("#id_name").val()},
url:"{% url "index" %}",
dataType:"html",
success:function (result) {
if(result=="no"){
$("#span1").text("用户名已存在!");
}else {
$("#span1").text("");
}
}
});
});
</script>
</html>
3 csrf跨站请求伪造
$.ajaxSetup({ data: {csrfmiddlewaretoken: \'{{ csrf_token }}\' }, });