本文会介绍三种ajax的请求方式:
- 原生的ajax请求
- JQuery的ajax的请求
- 伪造ajax请求
在一个网站上看到ajax是什么的一些说法:
AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
AJAX 不是新的编程语言,而是一种使用现有标准的新方法。
AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。
在使用form表单提交数据与后台进行交互的时候,是会刷新整个页面的,也就是会重新拉取整个页面的数据。而ajax做的就是局部刷新。只刷新部分页面,而不是刷新整个页面。
所有的实例以python3.6,django-1.10.8版本!
原生ajax:
ajax是基于现有的internet标准,并联合使用它们。包括以下的内容:
- XMLHttpRequest 对象 (异步的与服务器交换数据)
- JavaScript/DOM (信息显示/交互)
- CSS (给数据定义样式)
- XML (作为转换数据的格式)
使用ajax:
ajax的在使用中5个步骤:
- 创建XMLHttpResquest对象。
- 链接服务器
- 发送数据
- 设定回调函数
- 在回调函数中对服务器返回的数据进行处理
下面的一些ajax的函数,用于在上面的五个步骤中使用。

创建了对象之后,要向服务器发送数据。 open()函数用于创建ajax客户端与服务器之间的连接。 send()函数用于向服务器发送数据。 setRequestHeader()用于设置向服务器发送数据时的请求头。 ----void open(String method,String url,Boolen async) 用于创建请求 参数: method: 请求方式(字符串类型),如:POST、GET、DELETE... url: 要请求的地址(字符串类型) async: 是否异步(布尔类型)若使用ajax请求,必须为异步,就是值为true。 ----void send(String body) 用于发送请求 参数: body: 要发送的数据(字符串类型) ----void setRequestHeader(String header,String value) 用于设置请求头 参数: header: 请求头的key(字符串类型) vlaue: 请求头的value(字符串类型 服务器接收ajax发送的数据之后,需要返回数据给ajax客户端。 ----String getAllResponseHeaders() 获取所有响应头 返回值: 响应头数据(字符串类型) ----String getResponseHeader(String header) 获取响应头中指定header的值 参数: header: 响应头的key(字符串类型) 返回值: 响应头中指定的header对应的值 abort()方法终止请求。 XMLHttpRequest对象的主要属性: ---Number readyState 状态值(整数) 详细: 0-未初始化,尚未调用open()方法; 1-启动,调用了open()方法,未调用send()方法; 2-发送,已经调用了send()方法,未接收到响应; 3-接收,已经接收到部分响应数据; 4-完成,已经接收到全部响应数据; ---Function onreadystatechange 当readyState的值改变时自动触发执行其对应的函数(回调函数) ---String responseText 服务器返回的数据(字符串类型) ---XmlDocument responseXML 服务器返回的数据(Xml对象) ---Number states 状态码(整数),如:200、404... ---String statesText 状态文本(字符串),如:OK、NotFound...
通过一个简单的django实例,说明原生ajax的用法:
视图函数如下:
from django.shortcuts import render, HttpResponse # Create your views here. import json def ajax1(request): return render(request, "ajax1.html") def ajax1_json(request): print(request.POST) msg = {"code": 200, "msg": "What a fuck!"} return HttpResponse(json.dumps(msg))
简易的前端代码如下:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>测试ajax请求</title> </head> <body> <h1 id="i1">第一行内容</h1> <input type="button" value="ajax响应内容" onclick="changeContent();"> <script> function changeContent() { var xhr = new window.XMLHttpRequest(); xhr.open("POST", "/ajax1_json", true); xhr.setRequestHeader("flag","wangxz"); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8'); /* 注意如果数据是post方式传送,则必须数据的mtea格式*/ xhr.send("name=wangxz, pwd=123"); xhr.onreadystatechange = function () { if(xhr.readyState == 4){ console.log(xhr.responseText); var msg = JSON.parse(xhr.responseText); document.getElementById("i1").innerText=msg.msg; } } } </script> </body> </html>
上面的代码正常允许需要注释掉django中间件中有关csrf的认证,下面我们在ajax中加入csrftoken,但是引入了jquery。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>test ajax</title> <script src="/static/jquery.js"></script> </head> <body> <h1 id="i1">第一行内容</h1> <input type="button" value="ajax响应内容" onclick="changeContent();"> <script type="text/javascript">
// 定义一个函数获取cookie值,但是这里这个简单的服务器响应只返回来csrf的值 function getCookie(name) { var cookieValue = null; if (document.cookie && document.cookie !== '') { var cookies = document.cookie.split(';'); for (var i = 0; i < cookies.length; i++) { var cookie = jQuery.trim(cookies[i]); // Does this cookie string begin with the name we want? if (cookie.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } var csrftoken = getCookie('csrftoken'); console.log(csrftoken); //调试程序,打印出Csrf的值
function changeContent() { var xhr = new window.XMLHttpRequest(); xhr.open("POST","/ajax",true); xhr.setRequestHeader("flag","test"); xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset-UTF-8'); xhr.setRequestHeader("X-CSRFToken", csrftoken); //设置ajax请求的头部信息,把csrf的值放入到头部请求中 xhr.send("name='wangxz', pwd=123"); xhr.onreadystatechange = function () { if(xhr.readyState == 4){ console.log(xhr.responseText); var msg = JSON.parse(xhr.responseText); document.getElementById("i1").innerText=msg.msg; } } } </script> </body> </html>
jQuery ajax请求
jQuery封装了原始的ajax请求,因此使用jQuery请求会更方便一点。其模板文件如下:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>第一行内容</h1> <input type="button" onclick="changeContent();" value="Jquery改变内容"> <script src="/static/jquery.js"></script> <script> function changeContent() { $.ajax({ url: "ajax1_json", type: "POST", data: {"user":"root", "password":"123456"}, dataType: "json", /*dataType制定接受后端返回数据的格式,这个例子中如果不使用这个参数,接受的data数据,可以使用JSON.parse转换为json对象*/ success: function (data) { console.log(data); $("h1").text(data.msg); } }) } </script> </body> </html>
视图函数如下:
def jquery_ajax(request):
if request.method == "GET":
return render(request, "jquery_ajax.html")
elif request.method == "POST":
msg = {"code": 200, "msg": "What a fuck!"}
return HttpResponse(json.dumps(msg))
由以上的模板文件,可以发现JQuery中ajax请求,基本格式如下:
$.ajax({
url: "jquery_ajax", #ajax要传入的url
type: "POST", #传递数据的类型
data: {"user":"root", "password":"123456"}, # 要传递的数据
dataType: "json", #接收数据的类型
/*dataType制定接受后端返回数据的格式,这个例子中如果不使用这个参数,接受的data数据,可以使用JSON.parse转换为json对象*/
success: function (data) { #服务端响应成功后的回调函数
console.log(data);
$("h1").text(data.msg);
}
})
伪造ajax
可以利用html标签中的iframe标签伪造ajax请求,iframe标签会自动向后台提交数据。
iframe的前端代码如下:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>伪造ajax请求</title> <script src="/static/jquery.js"></script> </head> <body> <form action="/ajax1_json" method="post" target="ifm1"> <iframe id="ifm1" frameborder="1" name="ifm1"></iframe> <input type="text" name="user"> <input type="password" name="pwd"> <input type="submit" value="提交" onclick="submitForm();"> </form> <script> function submitForm() { $("#ifm1").load(function () { /* console.log(123); */ var text = $("#ifm1").contents().find("body").text(); console.log(text); }) } </script> </body> </html>
视图函数如下:
def ajax1_json(request): print(request.POST) msg = {"code": 200, "msg": "What a fuck!"} return HttpResponse(json.dumps(msg)) def wzajax(request): return render(request, "wzajax.html")
上面的三种ajax请求,一般若是传递的数据是文件,图片等一般数据优先使用iframe伪造ajax请求,然后使用jQuery,最后使用原生ajax。
iframe的标签是作为一个html文本嵌套在原html标签中的。iframe中的值,是服务端返回的值。注意在上面前端代码中,查找jframe标签值得方法。
利用三种ajax传递一张图片。
用三种方式上传一张照片,用iframe的方式实现预览的功能,前端代码如下:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> #f1{ width: 100px; height: 50px; opacity: 0; position: absolute; top: 0; bottom: 0; right: 0; left: 0; z-index: 100; } .c1{ display: inline-block;padding: 10px; background-color: #076aa5; position: absolute; top: 0; bottom: 0; right: 0; left: 0; z-index: 90; text-align: center; color: white; } .hide{ display: none; } </style> <script src="/static/jquery.js"></script> </head> <body> <div style="position: relative; 100px;height: 50px;"> <input type="file" name="f1" id="f1"> <a class="c1">上传</a> </div> <hr> <div> <input type="button" value="提交XHR" onclick="xhrSubmit();" /> <input type="button" value="提交jQuery" onclick="jqSubmit();" /> </div> <br><br> <!--iframe传输照片--> <form action="/upload" method="post" target="ifm1" enctype="multipart/form-data"> <input type="file" name="file1"> <iframe frameborder="1" name="ifm1" id="ifm1" style="display: none"></iframe> <input type="submit" value="iframe提交" onclick="ifmSubmit();"> <!--点击提交,iframe会自动提交,不会刷新当前整个页面--> </form> <!--预览,由iframe实现--> <div class="preview"></div> <script> function jqSubmit() { var file_obj = document.getElementById('f1').files[0]; var fd = new FormData(); fd.append("username", "wxz"); fd.append("file1", file_obj); $.ajax({ url: "/upload", type: "POST", data: fd, processData: false, // tell jQuery not to process the data contentType: false, // tell jQuery not to set contentType success: function (arg, a1, a2) { console.log(arg); console.log(a1); console.log(a2); } }) } function xhrSubmit() { var file_obj = document.getElementById('f1').files[0]; var fd = new FormData(); fd.append("username", "wxz"); fd.append("file1", file_obj); var xhr = new XMLHttpRequest(); xhr.open("POST", "/upload",true); xhr.onreadystatechange = function () { if(xhr.readyState == 4){ var obj = JSON.parse(xhr.responseText); console.log(obj); } }; xhr.send(fd); } function ifmSubmit() { $("#ifm1").load(function () { var text = $("#ifm1").contents().find("body").text(); var obj = JSON.parse(text); var img_tag = document.createElement("img"); img_tag.src = "/" + obj.img_msg; $(".preview").append(img_tag) }) } </script> </body> </html>
对应的视图函数如下:
def upload(request): if request.method == "GET": return render(request, "upload.html") elif request.method == "POST": username = request.POST.get("username") print("username") file1 = request.FILES.get("file1") print(file1) img_path = os.path.join("static/img/", file1.name) with open(img_path, "wb") as f: for item in file1.chunks(): f.write(item) msg = {"code": 200, "img_msg": img_path} return HttpResponse(json.dumps(msg))