ajax背景ajax对象ajax状态ajax与httpajax请求数据接口同步与异步ajax请求XML数据封装ajax函数artTemplate简介同源策略和跨域请求JSONP
Posted 苦海123
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ajax背景ajax对象ajax状态ajax与httpajax请求数据接口同步与异步ajax请求XML数据封装ajax函数artTemplate简介同源策略和跨域请求JSONP相关的知识,希望对你有一定的参考价值。
AJAX简介:
ajax背景:
1.AJAX(Asynchronous javascript And Xml)异步的 JavaScript 和 XML:ajax是浏览器提供的一套API,最早出现在谷歌浏览器,是在浏览器端进行网络编程(发送请求、接收响应)的技术方案。它可以使我们通过JavaScript直接获取服务端最新的内容而不必重新加载页面,让web更接近桌面应用的体验。
2.涉及到ajax操作的界面‘不能’使用文件协议(文件的方式)访问,实际是可以访问的。
3.ajax是一套API,核心提供的类型:XMLHttpRequest,其使用步骤如下:
<script>
// 1.创建 XMLHttpRequest 对象,xhr就类似浏览器的作用(发送请求 接收响应)
var xhr = new XMLHttpRequest(); //xhr变量名可以为其它名,习惯使用xhr;此对象有兼容问题,解决方法如下:
// 解决ajax的IE5-6兼容问题:
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXOBject('Microsoft.XMLHTTP');
// 2.打开浏览器输入网址,可以是服务端任何文件,比如 .txt或.php
xhr.open('GET', 'http://day-03.io/6.Ajax练习/01.ajax的背景/time.php'); //第一个参数为请求方式,第二个参数为请求地址
// 3.发送一个请求,如果是post请求方式,send里面可以传请求体,后面详细讲:
xhr.send();
// 4.响应,因为客户端永远不知道服务端何时才能返回我们的需求响应,所以,ajax API 采用时间机制(类似通知的方式):
xhr.onreadystatechange = function() {
// 这里this.readyState有三个阶段:2,3,4;写在xhr.open()下面会有状态1的出现,如果需要捕获第一个状态的变化,需要注意代码执行顺序的问题,有0-4五个状态,四个阶段;
if (this.readyState !== 4) return;//只有状态4表示请求响应已经完成,此时可以对数据进行操作:
// 5.看结果
console.log(this.responseText); //responseText可以接收到响应体,response也可以接收的响应体但是有区别
};
</script>
ajax中五种状态四种阶段代表什么:
ajax有五个状态,四种阶段,分别代表如下xhr.readyState的返回值:
<script>
var xhr = new XMLHttpRequest();
console.log(xhr.readyState);
// => 0:初始化,请求代理对象
xhr.open('GET', 'time.php');
console.log(xhr.readyState);
// => 1:open 方法已经调用,建立一个与服务端特定端口的连接
xhr.send();
xhr.addEventListener('readystatechange', function() {
switch (this.readyState) {
case 2:
// => 2:已经接收到了响应报文的响应头,但是还没有拿到体,this.getAllResponseHeaders()用来获取响应头
console.log(this.getResponseHeader('server'));
console.log(this.responseText);
break;
case 3:
// => 3:正在下载响应报文的响应体,有可能响应体为空,也有可能不完整,这里不能保证响应体数据的完整性
console.log(this.responseText);
break;
case 4:
// => 4:一切 OK ,整个响应报文已经完整下载下来了,请求体的数据是完整的
console.log(this.responseText);
break;
};
});
</script>
<script>
var xhr = new XMLHttpRequest(); //----安装一个浏览器
console.log(xhr.readyState); //--------------0:初始化请求代理
xhr.open('GET', 'time.php'); //打开一个浏览器,建立一个与服务端端口的连接
console.log(xhr.readyState); //--------------1:建立一个与服务端端口的连接
xhr.send(); //发送请求
console.log(xhr.readyState); //--------------1
// 用addEventListener()的方式注册事件:
xhr.addEventListener('readystatechange', function() {
// if (this.readyState!==4) return;
console.log(this.readyState); //-------------4,如果是注释掉上面的if条件,那么这里打印的值为:2,3,4,分别表示:
// 2:已经接收到响应体的响应头,还没有拿到响应体
// 3:正在下载响应体中
// 4:已经下载完一个完整的响应体
console.log(this.response); //服务端响应的东西,this.responseText也可以拿到响应体
// 在可以使用this的作用域建议使用this,因为这样可避免沿着作用域链一级一级的向下找,优化了性能。
});
</script>
onload事件代替readystatechange事件:
onload事件实现readystatechange事件效果:
<script>
var xhr = new XMLHttpRequest();
xhr.open('GET', 'time.php');
xhr.send(null);
xhr.onload = function() { //onload事件可以代替readystatechange事件,但是onload有兼容性问题,因此实际开发中依然不会使用onload
console.log(this.readyState);
console.log(this.responseText);
};
</script>
ajax遵循http协议:
ajax遵循http协议进行发送请求,在ajax中以post方式进行请求时注意:设置请求头中content-type属性及值,send()中以urlencoded格式设置请求体,如:
<script>
var xhr = new XMLHttpRequest();
xhr.open('POST', 'add.php'); //以POST的方式请求一个地址
//xhr.setRequestHeader('keyA', 'valueA'); //setRequestHeader用来设置一个请求头内容
// 请求体是 urlencoded 格式的内容,一定要设置请求头中的Content-Type 为'application/x-www-form-urlencoded'才可以正常请求:
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('key1=value1&key2=value2'); // 以 urlencoded 格式设置请求体
</script>
数据接口:
数据接口:能提供特定的能力,有输入有输出,返回数据的地址,如下面服务端代码的URL:users.php即为一个数据接口,详细如下:
服务端代码:
<?php
//这里使用假数据做测试,实际开发中可能会从数据库获取数据:
$data=array(
array(
'id'=>1,
'name'=>'法海',
'age'=>39
),
array(
'id'=>2,
'name'=>'如经',
'age'=>14
),
array(
'id'=>3,
'name'=>'道号',
'age'=>19
)
);
//当收到ajax发送的请求是做出相应的数据返回:
if(empty($_GET['id'])){
// 没有传递id返回所有数据,因为http协议中约定报文的内容是字符串,所以需要用json数据格式
$json = json_encode($data);//==>返回json字符串:[{"id":1,"name":"法海","age":39},{"id":2,"name":"如经","age":14},{"id":3,"name":"道号","age":19}]
echo $json;
}else{
foreach ($data as $item){
if($item['id']!=$_GET['id']) continue;
$json = json_encode($item);//==>[{"id":1,"name":"\\u5e08\\u5085","age":39}]
echo $json;
};
};
通过ajax请求数据接口的数据:
<script>
var listElement = document.getElementById('list');
var xhr = new XMLHttpRequest();
xhr.open('GET', 'users.php?id=' + this.id); //这里可以使用?传参请求到具体的值,若不传入参数,则拿回所有数据遍历;在一个readystatechange事件中可以继续new XMLHTTPRequest()请求数据
xhr.send();
xhr.onreadystatechange = function() {
if (this.readyState !== 4) return;
var data = JSON.parse(this.responseText); //将json字符串转换为json对象
//通过遍历的方式对数据data进行处理(渲染到页面):
for (var i = 0; i < data.length; i++) {
console.log(data[i].id + '--' + data[i].name + '---' + data[i].age); //打印拿到的所有数据
};
};
</script>
responseText和response区别:
responseTexxt返回的是普通字符串的形式的数据,不能通过 xhr.responseType='数据类型’设置返回的数据类型;response可以通过 xhr.responseType='数据类型’设置返回的数据类型。
<script>
var xhr = new XMLHttpRequest();
xhr.open('GET', 'test.php');
xhr.send();
xhr.responseType = 'json'; //有兼容问题
xhr.onreadystatechange = function() {
if (this.readyState === 4) {
// console.log(this.responseText);
console.log(this.response);
};
};
</script>
通过ajax发送post请求:
以post方式提交数据,需要注意:如果请求体是urlencoded格式,需要设置请求头的content-type,如:
以post方式通过ajax提交密码和用户名:
<script>
// 假设给按钮注册点击事件执行ajax请求提交数据:
getElement('btn').onclick = function() {
// 假设获取input中的值并给变量:
var username = getElement('username').value;
var password = getElement('password').value;
var xhr = new XMLHttpRequest(); //在js中开启一个浏览器
xhr.open('POST', 'data.php'); //打开浏览器并访问data.php
//如果请求体是 urlencoded 格式 必须设置请求头为:Content-Type','application/x-www-form-urlencoded'
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// xhr.send('username=' + username + '&password=' + password),发送请求体,字符串拼接不好操作,推荐使用模板字符串:
xhr.send(`username=${username}&password=${password}`);
// 3. 根据服务端的反馈 作出界面提示
xhr.onreadystatechange = function() {
if (this.readyState !== 4) return;
console.log(this.responseText); //若服务端有数据返回,则接收(服务端各个处理的反馈)
};
};
</script>
服务端对用户名和密码做校验并做反馈:
<?php
// 判断是否提交数据并做出反馈:
if(empty($_POST['username'])||empty($_POST['password'])){
exit('请提交用户名和密码');
};
// 接收客户端传过来的数据并给变量:
$username=$_POST['username'];
$password=$_POST['password'];
// 校验数据:通常使用数据库中的数据,这里使用假数据做测试:
if($username==='admin' && $password==='123'){
exit('登录成功!');
};
exit('用户名或者密码错误');
同步与异步模式:
同步模式:在相同的时间内只能做一件事情,ajax 操作会有楞等的情况,区别在于 send 方法会不会出现等待情况;
异步模式:在相同的时间内可以做不同的事情,比起同步模式,异步处理时间更短,但是时间差异不是很大,一般需要使用console.time()方法进行测试时间。
xhr.open()中的第三个参数async是控制是否开启异步模式,值为布尔值,默认是true则表示异步;
<script>
// 同步模式,加载时间长
var xhrSync = new XMLHttpRequest()
// open 方法的第三个参数是 async 可以传入一个布尔值,默认为 true
xhrSync.open('GET', 'time.php', false) //关闭异步模式
console.time('sync')
xhrSync.send() //关闭异步模式后,等待请求响应的过程完全完成后再继续
console.log(xhrSync.responseText)
// console.log('end request')
console.timeEnd('sync')
// 异步模式,加载时间短
var xhrSync = new XMLHttpRequest()
// open 方法的第三个参数是 async 可以传入一个布尔值,默认为 true
xhrSync.open('GET', 'time.php', true) //打开异步模式,默认是打开的
console.time('sync')
xhrSync.send()
console.log(xhrSync.responseText)
// console.log('end request')
console.timeEnd('sync')
</script>
ajax请求XML数据:
XML数据格式类似存在html标签中的内容,但是标签需要大写,文件后缀名为xml;ajax请求服务端xml数据时,需要指明响应头中content-type为application/xml,如:
ajax请求代码:
<script>
// 一般服务端响应一个简单的数据就是一个字符串,如果想要返回一个复杂的数据,一般采用json的格式;但是有很多老项目采用xml的方式存数据,此时也是需要获取数据的,如:
// ajax请求XML格式的数据:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'xml.php');
xhr.send();
xhr.onreadystatechange = function() {
if (this.readyState !== 4) return;
// this.responseXML 是专门用于获取服务端返回XML数据的,操作方式就是通过DOM(节点)的方式操作,但是需要服务端响应头中的 Content-Type 必须是 application/xml
// header('Content-Type: application/xml');---需要服务端响应头中的 Content-Type 必须是 application/xml
console.log(this.responseXML.documentElement.children[0].innerHTML)
console.log(this.responseXML.documentElement.getElementsByTagName('name')[0])
}
</script>
服务端XML数据:
<?php
header('Content-Type: application/xml');//告知响应头中响应文档类型为xml
?>
<?xml version="1.1" encoding="utf-8"?>
<person>
<name>小明</name>
<age>14</age>
<gender>男</gender>
</person>
<!-- 上面不能有空行,否则报错 -->
封装ajax函数:
实际开发中使用ajax获取数据的地方很多,为了节省开发成本,一般是将ajax封装成一个函数,使用时调用即可,我封装了一个名为ajax的AJAX数据请求函数,其中参数解释为:
method:必须,请求方式,
url:必须,请求路径
askbody:可选参数,当不需要向服务端传入参数时,可以给null占位,但是不能不写
callback:必须,一个用来处理响应数据的回调函数,回调函数中的参数即为响应结果
<script>
function ajax(method, url, askbody, callback) {
method = method.toUpperCase(); //当调用者输入的请求方式为小写字母时转大写
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXOBject('Microsoft.XMLHTTP'); //解决兼容问题
//默认请求体是字符串形式的,当调用者输入的是对象形式时,需要转换为字符串形式:
if (typeof askbody === 'object') {
var arr = []; //定义一个空数组用来对askbody进行拆解再拼接为字符串
for (var key in askbody) {
var value = askbody[key]; //通过遍历的的方式将请求体对象中的键拿到,并使用[键]的方式将对应的值拿到给变量value
arr.push(key + '=' + value); //将键和值作为一组元素追加到数组中
};
askbody = arr.join('&'); //将数组每个元素之间用&符号分割后转换为字符串形式,并重新给askbody,join可以将数组转化为字符串,括号中加参数则表示给每个元素之间添加的字符。
};
//如果是以get方式请求:将url和askbody进行拼接:
if (method === 'GET') {
url += '?' + askbody;
};
xhr.open(method, url);
//需要以post请求时,定义一个变量data接收请求体;当为get方式请求时,因为下面send中传入null或者不传,因此这里需要将data变量提升到整个函数作用域并初始值为null:
var data = null;
if (method === 'POST') { //当以post请求时,需要传入请求体,如下:
data = askbody; //将上面处理好的askbody赋值给data变量供下面send中使用
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); //当为post请求时,必须设置请求头中的Content-Type的值为application/x-www-form-urlencoded,且此代码要放到open的后面,否则会报错
};
xhr.send(data);
xhr.addEventListener('readystatechange', function() {<以上是关于ajax背景ajax对象ajax状态ajax与httpajax请求数据接口同步与异步ajax请求XML数据封装ajax函数artTemplate简介同源策略和跨域请求JSONP的主要内容,如果未能解决你的问题,请参考以下文章
AJAX 状态值(readyState)与状态码(status)详解
AJAX 状态值(readyState)与状态码(status)详解
AJAX 状态值(readyState)与状态码(status)详解