之前我们使用的是jQuery的Ajax,这是一种极为便捷的Ajax操作方式,但是我们还需要对Ajax技术进行进一步的了解。

    <input type="text" id="i1" />
+
<input type="text" id="i2" />
=
<input type="text" id="i3" /> <input type="button" id="btn1" value="jQuery Ajax" onclick="add1();" /> function add1(){
$.ajax({
url: '/add1/',
type: 'POST',
data: {'i1': $('#i1').val(),'i2': $('#i2').val()},
success:function(arg){
$('#i3').val(arg);
}
})
} #后台进行数值相加
def index(request):
return render(request,'index.html') def add1(request):
a1 = int(request.POST.get('i1'))
a2 = int(request.POST.get('i2'))
return HttpResponse(a1 + a2)

jQuery的Ajax生成页面计算器

  json序列化

  我们使用多种语言进行web开发,并且前后端使用的语言一般也不相同,怎么进行前后端的数据交互也成了一个问题。这里我们使用json来完成数据交互。

  JSON(JavaScript Object Notation,JS 对象标记) 是一种轻量级的数据交换格式。它基于 ECMAScript (w3c制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

  一幅图对比出js,json和python的数据类型对比:

  python的json模块可以进行json格式的序列化和反序列化操作。JavaScript使用parse和stringify方法进行json的数据转换:

JSON.parse():     用于将一个 JSON 字符串转换为 JavaScript 对象 
eg:
console.log(JSON.parse('{"name":"Yuan"}'));
console.log(JSON.parse('{name:"Yuan"}')) ; // 错误
console.log(JSON.parse('[12,undefined]')) ; // 错误 JSON.stringify(): 用于将 JavaScript 值转换为 JSON 字符串。 
eg: console.log(JSON.stringify({'name':"egon"})) ;
#合格json对象
["one", "two", "three"]
{ "one": 1, "two": 2, "three": 3 }
{"names": ["张三", "李四"] }
[ { "name": "张三"}, {"name": "李四"} ]
#不合格json对象
{ name: "张三", 'age': 32 } // 属性名必须使用双引号
[32, 64, 128, 0xFFF] // 不能使用十六进制值
{ "name": "张三", "age": undefined } // 不能使用undefined
{ "name": "张三",
"birthday": new Date('Fri, 26 Aug 2011 07:13:10 GMT'),
"getName": function() {return this.name;} // 不能使用函数和日期对象
}

json操作

  json的出现让我们的数据传输更快更节约带宽(json数据比xml数据更精简)。

<?xml version="1.0" encoding="utf-8"?>
<country>
<name>中国</name>
<province>
<name>黑龙江</name>
<cities>
<city>哈尔滨</city>
<city>大庆</city>
</cities>
</province>
<province>
<name>广东</name>
<cities>
<city>广州</city>
<city>深圳</city>
<city>珠海</city>
</cities>
</province>
<province>
<name>台湾</name>
<cities>
<city>台北</city>
<city>高雄</city>
</cities>
</province>
<province>
<name>新疆</name>
<cities>
<city>乌鲁木齐</city>
</cities>
</province>
</country>

不信就看看xml代码

  我们使用Ajax技术主要是因为:Ajax是异步交互并且浏览器页面局部刷新;(这一特点给用户的感受是在不知不觉中完成请求和响应过程),这一特性在前面帮我们解决了表单提交错误时保留上次填写信息的功能。

  Ajax传递csrf问题

  关于为什么要传递csrf的问题,这里就不详细说明了,前面写过关于跨站请求伪造的介绍。我们之前的csrf码都是跟随form表单一起提交到后台的。当然,我们使用Ajax也可以把csrf传递到后台。

#当js与html文件分离时,{{ csrf_token }} 无法被渲染失去作用
$.ajaxSetup({
data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
}); $.ajax({
#data: {csrfmiddlewaretoken: '{{ csrf_token }}' },//写在这也能传
})
#html body标签中必须存在{% csrf_token %}
{% csrf_token %} $.ajax({
url:"",
type:"POST",
data:{
csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val(),
}
})
#写到cookie基本通用
//<script src="{% static 'js/jquery.cookie.js' %}"></script> 需要下载对应文件
<script src="https://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.js"></script>
//要在前端进行cookie操作,可以使用这个插件
$.ajax({
headers:{"X-CSRFToken":$.cookie('csrftoken')},//必须加入请求头里面传递,django认证字段
//"X-CSRFToken"
})

  jQuery.serialize()

  serialize()函数用于序列化一组表单元素,将表单内容编码为用于提交的字符串。serialize()函数常用于将表单内容序列化,以便用于AJAX提交。该函数主要根据用于提交的有效表单控件的name和value,将它们拼接为一个可直接用于表单提交的文本字符串,该字符串已经过标准的URL编码处理(字符集编码为UTF-8)。该函数不会序列化不需要提交的表单控件,这和常规的表单提交行为是一致的。例如:不在<form>标签内的表单控件不会被提交、没有name属性的表单控件不会被提交、带有disabled属性的表单控件不会被提交、没有被选中的表单控件不会被提交。

  简单总结:就是说我们如果有很多input标签内容需要提交总不会全部写在data中罗列出来吧,这就用到serialize()函数了可以帮我们一次性提交数据到客户端。

<form name="myForm" action="http://www.365mini.com" method="post">
<input name="uid" type="hidden" value="" />
<input name="username" type="text" value="张三" />
<input name="password" type="text" value="" />
<select name="grade" id="grade">
<option value="">一年级</option>
<option value="">二年级</option>
<option value="" selected="selected">三年级</option>
<option value="">四年级</option>
<option value="">五年级</option>
<option value="">六年级</option>
</select>
<input name="sex" type="radio" checked="checked" value="" />男
<input name="sex" type="radio" value="" />女
<input name="hobby" type="checkbox" checked="checked" value="" />游泳
<input name="hobby" type="checkbox" checked="checked" value="" />跑步
<input name="hobby" type="checkbox" value="" />羽毛球
<input name="btn" id="btn" type="button" value="点击" />
</form>
//对于上面的form表单元素进行序列化可以直接序列化其内部的所有表单元素。
//序列化所有:$("form").serialize()
uid=1&username=%E5%BC%A0%E4%B8%89&password=123456&grade=3&sex=1&hobby=1&hobby=2
//部分序列化:$(":text, select, :checkbox").serialize()
username=%E5%BC%A0%E4%B8%89&password=123456&grade=3&hobby=1&hobby=2
在后台要取到form发回来的信息,只需要按照一般方式就可以取回来
request.POST.get("name") //input中的name属性

使用操作

  对于原生的Ajax来说,其实就是基于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() 终止请求

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...

XmlHttpRequest对象的主要属性

    <input type="text" id="i1" />
+
<input type="text" id="i2" />
=
<input type="text" id="i3" />
<input type="button" id="btn2" value="原生Ajax" onclick="add2();" /> function add2(){
var xhr = new XMLHttpRequest();//创建新对象
xhr.onreadystatechange = function(){//回调函数,后台有响应就执行
if(xhr.readyState == 4){
alert(xhr.responseText);//接收后台发回来的数据
}
};
xhr.open('GET','/add2/?i1=12&i2=19');//默认异步,用get传给后台数据在url中
xhr.send();}

  post方式的Ajax相对要复杂一些,因为涉及到请求体与request.POST的相关操作。

var xhr = new XMLHttpRequest();//创建新对象
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
alert(xhr.responseText);
}
};
xhr.open('POST','/add2/');
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');//请求头里必须有这个,post才能从请求体里拿到值
xhr.send("i1=12&i2=19");//在请求体里传值,只有send那么后台request.body中会传值但post中没值,post里的值也必须是这个格式
}//post实际上是从body中拿值转化成字典形式。csrf可以放到setheader里面

  除了XMLHttpRequest对象的5种状态的读取服务器响应结束时,客户端才会做出改变,我们还要关心服务器响应的状态码是否为200,其服务器响应为404,或500,那么就表示请求失败了。我们可以通过XMLHttpRequest对象的status属性得到服务器的状态码。

xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
alert(xmlHttp.responseText);
}
};

  伪Ajax(iframe+form)

  iframe标签可以不刷新发送HTTP请求(伪造局部刷新效果),同时他需要使用到form的数据打包功能,两者合一就是我们需要的Ajax默默地往后台发数据的功能。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div> <input type="text" id="txt1" />
<input type="button" value="查看" onclick="changeScr();"/> </div>
<iframe id="ifr" style="width: 1000px;height: 2000px;" src="http://www.autohome.com.cn"></iframe> <script>
function changeScr(){
var inp = document.getElementById('txt1').value;
alert(inp);
document.getElementById('ifr').src = inp;
}
</script>
</body>
</html>

iframe

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body> <form id="f1" method="POST" action="/fake_ajax/" target="ifr">{# target指定form的提交方式 #}
<iframe id="ifr" name="ifr" style="display: none"></iframe>{# 写哪都行,实际上它里面刷新了,内容就是返回值 #}
<input type="text" name="user" />
<a onclick="submitForm();">提交</a>
</form> <script>
function submitForm(){
document.getElementById('ifr').onload = loadIframe;//加载的时候执行这个函数
document.getElementById('f1').submit();//js提交 }
function loadIframe(){
var content = document.getElementById('ifr').contentWindow.document.body.innerText;//iframe标签取里面的值要使用这种方式
alert(content);
}
</script>
</body>
</html>

伪Ajax

  Ajax上传文件

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h1>原生Ajax上传文件</h1>
<input type="file" id="i1" />
<a onclick="upload1();">上传</a>
<div id="container1"></div> <h1>jQuery Ajax上传文件</h1>
<input type="file" id="i2" />
<a onclick="upload2();">上传</a>
<div id="container2"></div> <h1>伪 Ajax上传文件</h1>
<form id="f1" method="POST" action="/upload/" target="ifr" enctype="multipart/form-data">
<iframe id="ifr" name="ifr" style="display: none"></iframe>
<input type="file" name="fafafa" />
<a onclick="upload3();">上传</a>
</form>
<div id="container3"></div> <script src="/static/jquery-1.12.4.js"></script>
<script> function upload1(){
var formData = new FormData();
formData.append('k1','v1');
formData.append('fafafa',document.getElementById('i1').files[0]);//document.getElementById('i1').files[0]拿到文件对象 var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
var file_path = xhr.responseText;//xhr.responseText拿到后台传过来的数据
var tag = document.createElement('img');
tag.src = "/"+ file_path;
document.getElementById('container1').appendChild(tag); }
};
xhr.open('POST','/upload/');
xhr.send(formData);
} function upload2(){
var formData = new FormData();
formData.append('k1','v1');
// formData.append('fafafa',document.getElementById('i1').files[0]);
formData.append('fafafa',$('#i2')[0].files[0]);
// $('#i2') -> $('#i2')[0]转化成dom对象
// document.getElementById('i1') -> $(document.getElementById('i1'))转化成jQuery $.ajax({
url: '/upload/',
type: 'POST',
data: formData,
contentType:false,
processData:false,
success:function(arg){
var tag = document.createElement('img');
tag.src = "/"+ arg;
$('#container2').append(tag);
}
})
} function upload3(){
document.getElementById('ifr').onload = loadIframe;
document.getElementById('f1').submit(); }
function loadIframe(){
var content = document.getElementById('ifr').contentWindow.document.body.innerText;
var tag = document.createElement('img');
tag.src = "/"+ content;
$('#container3').append(tag);
}
</script>
</body>
</html>

三种方式的Ajax上传文件

  JSONP技术

  我们使用的Ajax技术只能访问自己的域名,如果我们使用Ajax向其他域名发送GET请求,由于浏览器的同源策略,我们并不会得到其他域名返回的html,jsonp则可以帮助我们做到(如果没有同源策略限制Ajax可以拿到任意的数据)。

同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。

什么是同源策略(百度百科)

  当我们需要用Ajax与其他域的url进行数据交互时,Ajax跨域发送请求默认在数据回来时浏览器拒绝接受。但是浏览器的同源策略对于带有src属性的标签(script标签),并没有阻止。jsonp就是利用的这一点完成的跨域。

  首先在jsonp的js中定义函数,

function list(arg){
console.log(arg);
}

  然后将请求的html地址放在script标签中,这样浏览器就没有办法阻止我们了。

<script src='http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403'></script>

  并且这个地址传给我们的返回值应当是执行我们定义的函数list,并且给list传了值的。

  我们没使用Ajax,而是jsonp,页面未刷新就获得了其他域名的值了(当然你要使用Ajax肯定是没问题的)。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<script src="/static/commons.js"></script> </head>
<body>
<a onclick="sendMsg();">发送</a> <script>
function sendMsg(){
var tag = document.createElement('script');
tag.src = "http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403";
document.head.appendChild(tag);
}
</script>
</body>
</html>

jsonp

  注:JSONP一定是GET请求。

Ajax及异步操作的更多相关文章

  1. Ajax实现异步操作实例_针对JSON格式的请求数据

    最近写了一篇ajax异步操作XML格式的,今天就写关于json格式的. 一.简单了解Json 1. JSON有两种表示结构,对象和数组. 1.1 对象: { key1:value1, key2:val ...

  2. Ajax实现异步操作实例_针对XML格式的请求数据

    js分类中有一节[原生js异步请求,XML解析]主要说明了js前台是如何处理XML格式请求和如何接受由服务器返回的XML数据的解析,今天我将用一个实例来说明具体要如何操作. 前台的参数类型也是XML使 ...

  3. ajax的异步操作及页面重定向跳转

    今天主要分享一个简单的ajax的异步操作数据,用javascript也有一段时间了,刚开始看到一些页面在没有页面刷新的情况下就可以实现数据的保存或者获取,觉得挺不可思议的,感觉速度很快,做了几个项目之 ...

  4. ajax实现异步操作实例1

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  5. jQuery源码分析系列(37) : Ajax 总结

    综合前面的分析,我们总结如下3大块: jQuery1.5以后,AJAX模块提供了三个新的方法用于管理.扩展AJAX请求 前置过滤器 jQuery. ajaxPrefilter 请求分发器 jQuery ...

  6. 【Java框架型项目从入门到装逼】第六节 - 用ajax请求后台数据

    这一节我们来说一下如何用ajax提交请求? 我们先不讲ajax的原理,还是先以实战为主,看一下这个东西到底怎么用的? form表单: <!-- 采用post表单提交 --> <for ...

  7. JS原生Ajax&Jquery的Ajax技术&Json

    1.介绍Ajax Ajax = 异步 JavaScript 和 XML Ajax是一种创建快速动态网页的技术 通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新.这意味着可以不用整个 ...

  8. jquery ajax 中实现给变量赋值

    我们在用JQuery的Ajax从后台提取数据后想把它赋值给全局变量,但是却怎么都赋不进,为什么呢? 原因其实很简单,我们用的Ajax是异步操作,也就是说在你赋值的时候数据还没提取出来,你当然赋不进去, ...

  9. vue+ajax+bootstrap+python实现增删改

    http://www.cnblogs.com/xwwin/p/5816527.html script src= " http://code.jquery.com/jquery.min.js ...

随机推荐

  1. solr安装配置

    1.solr是基于tomcat安装部署的 2.网上下载solr-5.2.1 http://lucene.apache.org/solr/downloads.html 3.解压solr文件 tar zx ...

  2. Java NIO (五) 管道 (Pipe)

    Java NIO 管道是2个线程之间的单向数据连接.Pipe有一个source通道和一个sink通道.数据会被写到sink通道,从source通道读取. 如下图: 向管道写数据: 从管道读数据: 1. ...

  3. Android短视频SDK转码实践

    一. 前言 一些涉及的基本概念: 转码:一般指多媒体文件格式的转换,比如分辨率.码率.封装格式等: 解复用(demux):从某种封装中分离出视频track和音频track,然后交给后续模块进行处理: ...

  4. Mysql 索引优化分析

    MySQL索引优化分析 为什么你写的sql查询慢?为什么你建的索引常失效?通过本章内容,你将学会MySQL性能下降的原因,索引的简介,索引创建的原则,explain命令的使用,以及explain输出字 ...

  5. CSS3 自定义动画(animation)

    除了在之前的文章中介绍过的 CSS3 的变形 (transformation) 和转换 (transition) 外,CSS3 还有一种自由度更大的自定义动画,开发者甚至可以使用变形(transfor ...

  6. 更好的小票打印体验,huanent.printer2.0发布

    huanent.printer2.0是一个专注消费小票打印的类库.拥有许多先进的特性例如居中打印.自动换行等特性,可以通过简洁的代码来打印出复杂的消费小票.huanent.printer通过MIT方式 ...

  7. esp8266 SDK开发之GPIO中断

    先秀一下自己焊的板子,黑的开关用于复位,蓝的开关用于烧录程序. 首先要明确的是esp8622的大多数管脚都有多个功能, 比如可以用来当做GPIO管脚,还可以用来当做SPI管脚. 如下图所示 使用PIN ...

  8. 数组a[n]中存放1-n中的n-1个数,给出算法找出重复的那一个数

    问题描述: 数组a[n]中存放1-n中的n-1个数,给出算法找出重复的那一个数. 算法一: 对数组a[n]进行冒泡排序,如果冒泡所得的最值和前一个最值相等,则该最值为重复的数. 分析: 该算法时间复杂 ...

  9. 浅谈JavaScript的面向对象程序设计(二)

    前面介绍通过Object构造函数或者字面量创建单个对象,但是通过这个的方法创建对象有明显的缺点:调用同一个接口创建多个实例,会产生大量的重复代码.怎么样解决? 工厂模式 工厂模式是软件工程领域经常使用 ...

  10. SpringMVC RequestMapping注解

    1.@RequestMapping 除了修饰方法,还可以修饰类 2.类定义处:提供初步的请求映射信息.相对于WEB应用的根目录  方法处:提供进一步细分映射信息  相对于类定义处的URL.若类定义处未 ...