编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

Python工程师带你分析必会框架Django之关于Ajax(附步骤和例子)

wxchong 2024-07-15 09:53:32 开源技术 11 ℃ 0 评论

一、原生的Ajax

Ajax主要就是使用 XmlHttpRequest对象来完成请求的操作,该对象在主流浏览器中均存在(除早起的IE),Ajax首次出现IE5.5中存在(ActiveX控件)。

1、XmlHttpRequest对象介绍

XmlHttpRequest对象的主要方法:

a. void open(String method,String url,Boolen async)
 用于创建请求(其实这里既是创建一个连接)
 参数:
 method: 请求方式(字符串类型),如:POST、GET、DELETE...
 url: 要请求的地址(字符串类型)
 async: 是否异步(布尔类型)
b. void send(String body)
 用于发送请求
 参数:
 body: 要发送的数据(字符串类型)
c. void setRequestHeader(String header,String value)
 用于设置请求头
 参数:
 header: 请求头的key(字符串类型)
 vlaue: 请求头的value(字符串类型)
d. String getAllResponseHeaders()
 获取所有响应头
 返回值:
 响应头数据(字符串类型)
e. String getResponseHeader(String header)
 获取响应头中指定header的值
 参数:
 header: 响应头的key(字符串类型)
 返回值:
 响应头中指定的header对应的值
f. void abort()
 终止请求

2、XmlHttpRequest对象的主要属性:

a. Number readyState
 状态值(整数)
 详细:
 0-未初始化,尚未调用open()方法;
 1-启动,调用了open()方法,未调用send()方法;
 2-发送,已经调用了send()方法,未接收到响应;
 3-接收,已经接收到部分响应数据;
 4-完成,已经接收到全部响应数据;
b. Function onreadystatechange
 当readyState的值改变时自动触发执行其对应的函数(回调函数)
c. String responseText
 服务器返回的数据(字符串类型)
d. XmlDocument responseXML
 服务器返回的数据(Xml对象)
e. Number states
 状态码(整数),如:200、404...
f. String statesText
 状态文本(字符串),如:OK、NotFound...

3、我们通过一个例子理解代码如下:

<!DOCTYPE html>
<html>
<head>
 <meta charset="UTF-8">
 <title>Title</title>
</head>
<body>
<input type="text">
<input type="button" value="Ajax1" onclick="Ajax1();">
<script>
 function Ajax1() {
 var xhr = new XMLHttpRequest();
 xhr.open("GET","/ajax_json/");
 //onreadystatechange其实就是一个回调函数,
 //只要readyState状态发生变化就会执行,
 //下面的方法表示只有状态为4是才执行函数下面的内容
 xhr.onreadystatechange=function () {
 if(xhr.readyState == 4){
//表示接收完毕
//responseText其实就是接受的内容
 console.log(xhr.responseText);
 var obj = JSON.parse(xhr.responseText)
 console.log(obj)
 }
 };
 //setRequestHeader设置请求头,可以设置csrf
 xhr.setRequestHeader("k1","v1");
 //发送信息
 xhr.send("name = root;pwd = 123");
 }
</script>
</body>
</html>

上述页面的效果,当点击ajax1提交的时候就会显示如下内容

上述的是通过GET,下面我们通过讲上述代码中的GET更改为POST,并且这里同时可以设置兼容问题,如微软的IE浏览器里面没有XMLHttpRequest

<!DOCTYPE html>
<html>
<head>
 <meta charset="UTF-8">
 <title>Title</title>
</head>
<body>
<input type="text">
<input type="button" value="Ajax1" onclick="Ajax1();">
<script>
 //用于兼容微软的IE浏览器
 function getXHR(){
 var xhr = null;
 if(XMLHttpRequest){
 xhr = new XMLHttpRequest();
 }else{
 xhr = new ActiveXObject("Microsoft.XMLHTTP");
 }
 return xhr;
 }
 function Ajax1() {
 var xhr = getXHR();
 xhr.open("POST","/ajax_json/");
 xhr.onreadystatechange=function () {
 if(xhr.readyState == 4){
 //表示接收完毕
 console.log(xhr.responseText);
 var obj = JSON.parse(xhr.responseText)
 console.log(obj)
 }
 };
 //通过原生的ajax发送post的请求的时候必须设置请求头,否则发送不到后台
 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
 xhr.send("name = root;pwd = 123");
 }
</script>
</body>
</html>

二、伪Ajax

由于HTML标签的iframe标签具有局部加载内容的特性,所以可以使用其来伪造Ajax请求。

<!DOCTYPE html>
<html>
<head>
 <meta charset="UTF-8">
 <title>Title</title>
</head>
<body>
<form action="/ajax_json/" method="POST" target="ifml">
 <iframe id = "ifml" name="ifml"></iframe>
 <input type="text" name="username">
 <input type="text" name="email">
 <input type="submit" name="Form提交" onclick="sumbitForm();">
</form>
<script type="text/javascript" src="/static/jquery-1.12.4.js"></script>
<script>
 function sumbitForm() {
 $("#ifml").load(function () {
 //iframe在html页面中其实在html页面中包含了一个html页面,
 //及时上下文的关系,所以这里需要
 //通过contents()获得iframe中的内容然后通过find找到body中的内容
 var text = $("#ifml").contents().find("body").text();
 var obj = JSON.parse(text);
 console.log(obj)
 })
 }
</script>
</body>
</html>

这里面有一个地方需要注意就是iframe部分的内容在页面中其实也是一个完整的html,如下所示:

所以通过js操作的时候不能直接找到iframe标签然后text,需要通过contents()获取iframe中的内容,最后通过find找到自己需要的数据,这样当我们点击页面的提交的时候就可以在js中获取返回数据

三、通过原生Ajax、jquery、伪Ajax实现上传数据

通过三种不同的方式实现文件上传或者图片上传的功能,html中的代码如下:

<!DOCTYPE html>
<html>
<head>
 <meta charset="UTF-8">
 <title>Title</title>
 <style>
 .upload{
 display: inline-block;
 background-color: aqua;
 position: absolute;
 top:0;
 bottom: 0;
 right:0;
 left:0;
 z-index: 90;
 text-align: center;
 line-height: 50px;
 }
 .file{
 width: 100px;
 height: 50px;
 opacity: 0;
 position: absolute;
 top:0;
 bottom: 0;
 right:0;
 left:0;
 z-index: 100;
 }
 </style>
</head>
<body>
<div style="position: relative;width: 100px;height: 50px">
 <input type="file" id="fafa" name="fafa">
 <a>上传</a>
</div>
<input type="button" value="提交XHR" onclick="xhrSubmit();">
<input type="button" value="提交jQuery" onclick="jqSubmit();">
<hr/>
<form id="fm1" action="/upload_file/" method="POST" enctype="multipart/form-data" target="ifml">
 <iframe id = "ifml" name="ifml" style="display: none"></iframe>
 <input type="file" name="fafa" onchange="changeUpload();">
{# <input type="submit" name="Form提交" onclick="iframeSubmit();">#}
</form>
<div id="preview"></div>
<script src="/static/jquery-1.12.4.js"></script>
<script>
 function changeUpload() {
 $("#ifml").load(function () {
 //iframe在html页面中其实在html页面中包含了一个html页面,及时上下文的关系,所以这里需要
 //通过contents()获得iframe中的内容然后通过find找到body中的内容
 var text = $("#ifml").contents().find("body").text();
 var obj = JSON.parse(text);
 console.log(obj);
 $("#preview").empty();
 var imgTag = document.createElement("img");
 imgTag.src="/"+obj.data;
 $("#preview").append(imgTag)
 })
 $("#fm1").submit();
 }
 //通过原生的ajax上传文件
 function xhrSubmit() {
 //这里获得就是上传文件的对象
 var file_obj = document.getElementById("fafa").files[0];
 //FormData就相当于是一个Form表单,但是不是所有的浏览器支持,如IE浏览器不支持
 var fd = new FormData();
 fd.append("username","root");
 fd.append("fafa",file_obj);
 var xhr =new XMLHttpRequest();
 xhr.open("POST","/upload_file/");
 xhr.onreadystatechange=function () {
 if(xhr.readyState == 4){
 //表示接收完毕
 console.log(xhr.responseText);
 var obj = JSON.parse(xhr.responseText);
 console.log(obj)
 }
 };
 xhr.send(fd);
 }
 //通过jQuery上传文件
 function jqSubmit() {
 var file_obj = document.getElementById("fafa").files[0];
 //FormData就相当于是一个Form表单,但是不是所有的浏览器支持,如IE浏览器不支持
 var fd = new FormData();
 fd.append("username","root");
 fd.append("fafa",file_obj);
 $.ajax({
 url:"/upload_file/",
 type:"POST",
 data:fd,
 //jquery就会对发送的数据进行处理,也就是进行字符串拼接
 //就如同我们通过原生的发送数据时如:xhr.send("name = root;pwd = 123");,所以普通的上传不会影响
 //但是传文件时为了防止jquery进行上述的处理,需要添加下面内容
 processData:false,
 contentType:false,
 //从打印结果可以看出,success成功之后的这个回调函数有是三个参数,
 // 第一个是返回的数据的对象
 //第二个是返回的状态,成功则是success
 //第三个其实就是xmlhttprequest对象
 success:function (arg,a1,a2) {
 console.log(arg);
 console.log(a1);
 console.log(a2);
 }
 })
 }
 //通过伪Ajax即iframe上传文件,兼容所有的浏览器
 function iframeSubmit() {
 $("#ifml").load(function () {
 //iframe在html页面中其实在html页面中包含了一个html页面,及时上下文的关系,所以这里需要
 //通过contents()获得iframe中的内容然后通过find找到body中的内容
 var text = $("#ifml").contents().find("body").text();
 var obj = JSON.parse(text);
 console.log(obj);
 $("#preview").empty();
 var imgTag = document.createElement("img");
 imgTag.src="/"+obj.data;
 $("#preview").append(imgTag)
 })
 }
</script>
</body>
</html>

上述代码中分别通过三种方式实现了上传图片的功能,同事以iframe为例实现预览的功能。注意:iframe方法的兼容性是最好的,在所有浏览器都支持

四、小结:

如果是发送普通数据,jQuery,XMLHttpRequest,iframe的优先级使用:

jQuery---->XMLHttpRequest----->iframe

如果是发送文件jQuery,XMLHttpRequest,iframe的优先级使用:

iframe(伪Ajax) ----> jQuery(FormData) ----> XMLHttpRequest(FormData)


以上是全部内容,只是善于分享,不足之处请包涵!爬虫基本的原理就是,获取源码,进而获取网页内容。一般来说,只要你给一个入口,通过分析,可以找到无限个其他相关的你需要的资源,进而进行爬取。


我也写了很多其他的非常简单的入门级的爬虫详细教程,

关注后,点击我的头像,就可以查看到。

欢迎大家一起留言讨论和交流,谢谢!

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表