1.AJAX的定义:
AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术。Ajax不是一种新的编程语言,而是使用现有标准的新方法。AJAX可以在不重新加载整个页面的情况下,与服务器交换数据。这种异步交互的方式,使用户单击后,不必刷新页面也能获取新数据。使用Ajax,用户可以创建接近本地桌面应用的直接、高可用、更丰富、更动态的Web用户界面。
Ajax包括:
- XHTML和CSS
- 使用文档对象模型(Document Object Model)作动态显示和交互
- 使用XML和XSLT做数据交互和操作
- 使用XMLHttpRequest进行异步数据接收
利用AJAX可以做:
-注册时,输入用户名自动检测用户是否已经存在。
-登陆时,提示用户名密码错误。
- 删除数据行时,将行ID发送到后台,后台在数据库中删除,数据库删除成功后,在页面DOM中将数据行也删除。(博客园)
2.伪造AJAX
所谓的伪造ajax就是通过<iframe></iframe>
标签里的src仿造,我们常用的iframe实际上是框架的一种形式,该标签一般是用来加载我们自己网站或者是其他网站内容的一种形式。iframe具有局部加载的特性,因此可以使用iframe来伪造AJAX请求。
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>伪造AJAX</title>
</head>
<body>
<div>
<p>请输入要加载的地址:<span id="currentTime"></span></p>
<p>
<input id="url" type="text" />
<input type="button" value="提交" onclick="LoadPage();">
</p>
</div>
<div>
<h3>加载页面位置:</h3>
<iframe id="iframePosition" style="width: 100%;height: 500px;"></iframe>
</div>
<script type="text/javascript">
window.onload= function(){
var myDate = new Date();
document.getElementById('currentTime').innerText = myDate.getTime();
};
function LoadPage(){
var targetUrl = document.getElementById('url').value;
document.getElementById("iframePosition").src = targetUrl;
}
</script>
</body>
</html>
以上代码的原理如下:设置一个提交按钮,在设置一个输入框,用于接受我们输入的地址,点击后将改地址赋值给到iframe的src,就可以做到在不刷新页面的情况下,刷新iframe里面的内容。
3.原生AJAX
一、XMLHttpRequest对象
Ajax的核心是XMLHttpRequest(xhr)对象,XHR为向服务器发送数据和接受服务器的响应提供了接口,能够以异步的方式从服务器获取数据。
XHR的主要方法:
void open(String method,String url,Boolean asyn)
用于创建请求
参数说明:
method:请求方式。(POST,GET,DELETE...)
url:请求路径
asyn:是否异步
void send(String body)
用于发送数据
参数说明:
void setRequestHeader(String header,String value)
用于设置请求头
参数说明:
header:请求头的key
value:请求头的value
String getAllResponseHeaders()
获取所有响应头
返回值:
响应头的所有数据
String getResponseHeader(String header)
获取响应头中指定header的值:
参数说明:
header:响应头的key
返回值:
指定响应头的value
void abort()
终止响应
XHR的主要属性:
Number readyState :状态值,整数,可以确定当前请求响应的过程中的当前活动阶段
0:未初始化,未调用open()方法;
1:启动,已调用open()方法,未调用send()方法
2:发送,调用send()方法,未接受到响应
3:接收,已经接收到部分数据,
4:完成,已接收到完整的数据,可以在客户端使用
function onreadystatechange:当readyState值改变时自动触发调用器对应的函数(回调函数)
String responseText: 作为响应主体被返回的文本
XmlDocument responseXML :服务器返回的数据(Xml对象)
Number states:状态码,如404,200……
String statesText:状态文本(字符串),如:OK、NotFound…
二、GET请求
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h1>XMLHttpRequest - Ajax请求</h1>
<input type="button" onclick="XmlGetRequest();" value="Get发送请求" />
<script src="/statics/jquery-1.12.4.js"></script>
<script type="text/javascript">
function GetXHR(){
var xhr = null;
if(XMLHttpRequest){
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
return xhr;
}
function XmlGetRequest(){
var xhr = GetXHR();
// 定义回调函数
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
// 已经接收到全部响应数据,执行以下操作
var data = xhr.responseText;
console.log(data);
}
};
// 指定连接方式和地址----文件方式
xhr.open('get', "/test/", true);
// 发送请求
xhr.send();
}
</script>
</body>
</html>
三、POST请求
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>POST</title>
</head>
<body>
<h1>XMLHttpRequest - Ajax请求</h1>
<input type="button" onclick="XmlPostRequest();" value="Post发送请求" />
<script src="/statics/jquery-1.12.4.js"></script>
<script type="text/javascript">
function GetXHR(){
var xhr = null;
if(XMLHttpRequest){
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
return xhr;
}
function XmlPostRequest(){
var xhr = GetXHR();
// 定义回调函数
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
// 已经接收到全部响应数据,执行以下操作
var data = xhr.responseText;
console.log(data);
}
};
// 指定连接方式和地址----文件方式
xhr.open('POST', "/test/", true);
// 设置请求头
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
// 发送请求
xhr.send('n1=1;n2=2;');
}
</script>
</body>
</html>
三、jQuery Ajax
通过 jquery AJAX 方法,您能够使用 HTTP Get 和 HTTP Post 从远程服务器上请求文本、HTML、XML 或 JSON – 同时您能够把这些外部数据直接载入网页的被选元素中。
jQuery 不是生产者,而是大自然搬运工。
jQuery Ajax本质 XMLHttpRequest 或 ActiveXObject
1. jQuery.get(...)
所有参数:
url: 待载入页面的URL地址
data: 待发送 Key/value 参数。
success: 载入成功时回调函数。
dataType: 返回内容格式,xml, json, script, text, html
2.jQuery.post(...)
所有参数:
url: 待载入页面的URL地址
data: 待发送 Key/value 参数
success: 载入成功时回调函数
dataType: 返回内容格式,xml, json, script, text, html
3.jQuery.getJSON(...)
所有参数:
url: 待载入页面的URL地址
data: 待发送 Key/value 参数。
success: 载入成功时回调函数。
4.jQuery.getScript(...)
所有参数:
url: 待载入页面的URL地址
data: 待发送 Key/value 参数。
success: 载入成功时回调函数。
5.jQuery.ajax(...)
部分参数:
url:请求地址
type:请求方式,GET、POST(1.9.0之后用method)
headers:请求头
data:要发送的数据
contentType:即将发送信息至服务器的内容编码类型(默认: "application/x-www-form-urlencoded; charset=UTF-8")
async:是否异步
timeout:设置请求超时时间(毫秒)
beforeSend:发送请求前执行的函数(全局)
complete:完成之后执行的回调函数(全局)
success:成功之后执行的回调函数(全局)
error:失败之后执行的回调函数(全局)
accepts:通过请求头发送给服务器,告诉服务器当前客户端课接受的数据类型
dataType:将服务器端返回的数据转换成指定类型
"xml": 将服务器端返回的内容转换成xml格式
"text": 将服务器端返回的内容转换成普通文本格式
"html": 将服务器端返回的内容转换成普通文本格式,在插入DOM中时,如果包含JavaScript标签,则会尝试去执行。
"script": 尝试将返回值当作JavaScript去执行,然后再将服务器端返回的内容转换成普通文本格式
"json": 将服务器端返回的内容转换成相应的JavaScript对象
"jsonp": JSONP 格式使用 JSONP 形式调用函数时,如 "myurl?callback=?" jQuery 将自动替换 ? 为正确的函数名,以执行回调函数
例如:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<p>
<input type="button" onclick="XmlSendRequest();" value='Ajax请求' />
</p>
<script type="text/javascript" src="jquery-1.12.4.js"></script>
<script>
function JXmlSendRequest(){
$.ajax({
url: "http://c2.com:8000/test/", // 访问url地址
type: 'GET', // get方式提交
dataType: 'text', // 数据类型
success: function(data, statusText, xmlHttpRequest){ // 成功后返回的结果
console.log(data);
}
})
}
</script>
</body>
</html>
四、Ajax跨域
由于浏览器存在同源策略机制,同源策略阻止从一个源加载的文档或者脚本获取或者设置另一个源加载的文档属性,所以ajax本身是不可以跨域的,通过产生一个script标签来实现跨域,因为script标签的src属性是没有跨域的限制的。
浏览器的同源策略并不是对所有的请求均制约:
制约:XmlHttpRequest
不至约: img、iframe、script等具有src属性的标签
注:自己模拟跨域,需要现在自己电脑的host文件里面添加两条域名,我这里添加的是zhangyanlin.com和aylin.com这两个域名
1、JSONP实现跨域请求
JSONP是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问。jsonp只能通过get方式进行跨域请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="button" value="Ajax" onclick="DoAjax();"/>
<input type="button" value="JsonpAjax" onclick="JsonpAjax();"/>
<script src="/statics/jquery-1.12.4.js"></script>
<script src="http://aylin.com:8002/statics/jquery.cookie.js"></script>
<script>
function func(arg) {
console.log(arg); // 输出结果就是python代码给传过来的列表[11,22,33,]
}
function DoAjax() {
$.ajax({
url: 'http://alex.com:8002/index',
type: 'POST',
data: {'k1': 'v1'},
success: function (arg) {
console.log(arg);
}
});
}
function JsonpAjax() {
// var tag = document.createElement('script');
// tag.src = "http://alex.com:8002/index";
// document.head.appendChild(tag);
// document.head.removeChild(tag);
$.ajax({
url: "http://aylin.com:8002/index",
dataType: 'jsonp',
jsonpCallBack: 'func' // 对端给返回函数名,函数接收的参数是内容
})
}
</script>
</body>
</html>
aylin.com域名这边可以给定义函数
# 采用pythontornado框架来进行的
class IndexHandler(tornado.web.RequestHandler):
def get(self):
self.write('func([11,22,33]);')
def post(self, *args, **kwargs):
self.write('t2.post')
在这里jsonp就采用script标签的src来进行跨域请求的
2、CORS
上面那种方法说到浏览器的同源策略导致ajax无法进行跨域传输,那么这种方法就可以突破浏览器限制来进行传输。当数据发送给对方域名的时候,对方已经收到,但是在返回的时候被浏览器给阻挡,我们可以写一串类似于身份证的字符串,通过浏览器的预检,从而达到数据的传输。
这方面分为简单请求和非简单请求
条件:
1、请求方式:HEAD、GET、POST
2、请求头信息:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type 对应的值是以下三个中的任意一个
application/x-www-form-urlencoded
multipart/form-data
text/plain
注意:同时满足以上两个条件时,则是简单请求,否则为复杂请求
基于cors实现AJAX请求:
I、支持跨域,简单请求
服务器设置响应头:Access-Control-Allow-Origin = ‘域名’ 或 ‘*’
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<p>
<input type="submit" onclick="XmlSendRequest();" />
</p>
<p>
<input type="submit" onclick="JqSendRequest();" />
</p>
<script type="text/javascript" src="jquery-1.12.4.js"></script>
<script>
function XmlSendRequest(){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4) {
var result = xhr.responseText;
console.log(result);
}
};
xhr.open('GET', "http://c2.com:8000/test/", true);
xhr.send();
}
function JqSendRequest(){
$.ajax({
url: "http://c2.com:8000/test/",
type: 'GET',
dataType: 'text',
success: function(data, statusText, xmlHttpRequest){
console.log(data);
}
})
}
</script>
</body>
</html>
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com")
self.write('{"status": true, "data": "seven"}')
II、支持跨域,复杂请求
由于复杂请求时,首先会发送“预检”请求,如果“预检”成功,则发送真实数据。
“预检”请求时,允许请求方式则需服务器设置响应头:Access-Control-Request-Method
“预检”请求时,允许请求头则需服务器设置响应头:Access-Control-Request-Headers
“预检”缓存时间,服务器设置响应头:Access-Control-Max-Age
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<p>
<input type="submit" onclick="XmlSendRequest();" />
</p>
<p>
<input type="submit" onclick="JqSendRequest();" />
</p>
<script type="text/javascript" src="jquery-1.12.4.js"></script>
<script>
function XmlSendRequest(){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4) {
var result = xhr.responseText;
console.log(result);
}
};
xhr.open('PUT', "http://aylin.com:8000/test/", true);
xhr.setRequestHeader('k1', 'v1');
xhr.send();
}
function JqSendRequest(){
$.ajax({
url: "http://aylin.com:8000/test/",
type: 'PUT',
dataType: 'text',
headers: {'k1': 'v1'},
success: function(data, statusText, xmlHttpRequest){
console.log(data);
}
})
}
</script>
</body>
</html>
class MainHandler(tornado.web.RequestHandler):
def put(self):
self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com")
self.write('{"status": true, "data": "seven"}')
def options(self, *args, **kwargs):
self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com")
self.set_header('Access-Control-Allow-Headers', "k1,k2")
self.set_header('Access-Control-Allow-Methods', "PUT,DELETE")
self.set_header('Access-Control-Max-Age', 10)
III、跨域传输cookie
在跨域请求中,默认情况下,HTTP Authentication信息,Cookie头以及用户的SSL证书无论在预检请求中或是在实际请求都是不会被发送。
如果想要发送:
**浏览器端:XMLHttpRequest的withCredentials为true
服务器端:Access-Control-Allow-Credentials为true
注意:服务器端响应的 Access-Control-Allow-Origin 不能是通配符 **
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<p>
<input type="submit" onclick="XmlSendRequest();" />
</p>
<p>
<input type="submit" onclick="JqSendRequest();" />
</p>
<script type="text/javascript" src="jquery-1.12.4.js"></script>
<script>
function XmlSendRequest(){
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4) {
var result = xhr.responseText;
console.log(result);
}
};
xhr.withCredentials = true;
xhr.open('PUT', "http://aylin.com:8000/test/", true);
xhr.setRequestHeader('k1', 'v1');
xhr.send();
}
function JqSendRequest(){
$.ajax({
url: "http://aylin.com:8000/test/",
type: 'PUT',
dataType: 'text',
headers: {'k1': 'v1'},
xhrFields:{withCredentials: true},
success: function(data, statusText, xmlHttpRequest){
console.log(data);
}
})
}
</script>
</body>
</html>
class MainHandler(tornado.web.RequestHandler):
def put(self):
self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com")
self.set_header('Access-Control-Allow-Credentials', "true")
self.set_header('xxoo', "seven")
self.set_header('zhangyanlinhenshuai', "feichangshuai")
self.set_header('Access-Control-Expose-Headers', "shuai,shuaishuai")
self.set_cookie('kkkkk', 'vvvvv');
self.write('{"status": true, "data": "seven"}')
def options(self, *args, **kwargs):
self.set_header('Access-Control-Allow-Origin', "http://www.xxx.com")
self.set_header('Access-Control-Allow-Headers', "k1,k2")
self.set_header('Access-Control-Allow-Methods', "PUT,DELETE")
self.set_header('Access-Control-Max-Age', 10)
本文章转载自《史上最全ajax全套》,转载请注明原著作者。