0x00:什么是Ajax?

  Ajax是Asynchronous Javascript And Xml 的缩写(异步javascript及xml),Ajax是使用javascript在浏览器后台操作HTTP和web服务器进行数据交换(用户不知道也感觉不出来,就跟桌面应用程序似的进行数据交互),它不会导致页面重新加载,这样才有更好的用户体验。

  Ajax是基于以下开放标准:

  • javascript(DOM)
  • css
  • html
  • xml(json)

通俗的说就是使用了javascript(DOM)的XMLHttpRequest对象(ajax核心API也是浏览器的http API)及后续一系列的操作(发送和接收操作),接收来自服务器xml(json)等数据格式的数据,用html和css来显示出来。所以它们只是组合出来的一种新的技术。

历史什么的我就不介绍了。

0x01:怎样使用Ajax?

  001:实例化一个XMLHttpRequest对象

  var xhr = new XMLHttpReques();

就是这么简单。一般不用考虑兼容性,如果你想让每一用户都能享受到ajax带来的福利。你还要考虑我们IE5,6的朋友(现在应该用的不多了吧,具体我也不知道);

你可以定义一个实例化这个对象的函数:

function createXHR() {

    if(window.XMLHttpRequest) {
return new XMLHttpRequest();
} else if(window.ActiveXObject) {
return new ActiveXObject(Microsoft.XMLHTTP);
}
}

这就兼容一切浏览器了。

002:发送请求

    实例化对象后,就要发送请求了,要使用XMLHttpRequest对象的open()和send()方法及可选setRequestHeader()方法(请求头设置)。

    首先来说open()方法。它可以接受三个参数,第一个参数是要发送的请求的类型(即GET,POST等),第二个参数是请求的URL(网址)(即服务器上文件的地址,但不能跨域请求),第三个参数是一个布尔值(true表示异步,false表示同步)。

    细节

      the first argument:第一个参数GET,POST等是不区分大小写的,但是通用的做法是都用大写。

        那什么时候用GET,什么时候用POST呢?

        GET简单说就是向服务器请求查询资源时用,请求不对服务器有任何副作用,是幂等的(即对同一url多次请求应该返回相同的结果)

        具体以下是GET请求的特点,你可以根据这些特点来使用

          1.GET请求的响应可以被浏览器缓存

          2.GET请求有长度限制(具体跟浏览器和服务器自身设置有关一般可以2k-8k) 

          3.GET请求可以在历史记录中查看,(如果发送了敏感数据,别人通过查看你的历史记录就能看见)

          4.GET请求可以保存为书签

          5.GET请求只有请求头,没有主体,要设置查询字符串参数,首先要进行编码,然后把数据放在url后面,用?把地址和查询参数隔开,

           查询参数之间用&隔开例如:www.123.com/aa.php?name=‘wy’l&id=001;url地址栏所以也不能发送敏感数据,用户能看见了。

        POST是向服务器发送要处理的数据时用

        具体以下是POST请求的特点。

          1.一般不对请求的数据的长度进行限制

          2.浏览器不进行缓存文件、数据,无法使用缓存文件等

          3.数据在主体中,相对GET安全点,一般用户看不见,要是用工具那就另说了,get可能造成CSRF攻击

          4.发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠

根据这些特点你就知道该什么时候用GET和POST。

       the second argument:第二个参数,需要注意的是,不能进行跨域请求。什么是跨域呢,就是当两个url中只要

       其中一项不同就是跨域,协议,域名,端口不同就是跨域,具体如下截图,看懂就明白了。

截图来自:http://www.cnblogs.com/rainman/archive/2011/02/20/1959325.html

      the third argument:第三个参数是可以省略的,那就默认异步(true),异步和同步在不同的地方解释会有不同,这里是的意思是,同步的话会阻塞javascript的执行,就是说在调用send()方法后,浏览器就会在这个地方停止后面的代码执行,一直到服务器响应,才再往下执行后面的代码,如果用异步的话,javascript就会在调用了send()方法后,不会等待服务器的响应,继续执行下面的代码,但是你也不能不管了吧,这里就会说到下面要讲的要进行事件监听,当你服务器有响应了,我再去操作你的数据等操作。

说了半天也没有说代码是怎么样的:

//GET请求
xhr.open("GET","www.123.com/bb.php")
xhr.open("GET","www.123.com/bb.php?a=2&b=3")//如果你要加上查询数据的话
//POST请求
xhr.open("POST","www.123.com/aa.php")

在说send()方法之前还要说,请求头的设置,如果是GET请求,这一步可以没有,但是要是POST表单编码请求必须要设置“Content-Type”头来指定请求的主题的MIME类型(就是告诉服务器我给的是什么类型的数据)值为:application/x-www-form-urlencoded。它的值还有值可以是application/json,text/plain,text/html,text/xml等,有时候XMLHttpRequest对象会自动识别你发送数据的类型,所以你也可以没有,但是最好设置上。其他的如果你有特殊需要你就设置;有一些头是你不能自己设置,如Content-Length,Date,Referer,User-Agent等,除了这些你都可以自己设置,不需要的浏览器就发送自己默认的请求头。如果对相同的头调用setRequestHeader()多次,新值不会取代之前的值,而是HTTP请求头包含这个头的多个副本或者这个头将指定多个值。

设置请求头用setRequestHeader()方法。一定要注意了,必须在调用open()方法之后,并且在调用send()方法之前调用setRequestHeader()方法。

post用:

xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8");//表单编码的请求

现在真是说send()方法。先说GET下的send(),

xhr.send();//可以这样
xhr.send(null);//也可以这样,传递一个null,最好设置为null,说有些浏览器不设置为null会报错,所以推荐这样

POST:

xhr.send(msg)//请求的主体要发送内容

之后一次请求就这样被发送到服务器了,接下来就等着响应数据了,来进一步进行操作了。

003:等待响应

可以使用XMLHttpRequest对象的一些属性和方法来检测服务器的响应。

    首先说readyState属性和readystatechange事件。

 redayState属性表示请求或响应过程处于当前的什么阶段了,它是用一个整数表示的0-4。我看见关于这个状态的每个整数代表的什么状态,说的稍微有点混乱或者说不太明确。我就测试了一下post下的情况,先上测试代码:

window.addEventListener("load",function() {
var request = new XMLHttpRequest();
console.log("初始化对象时--" + request.readyState);//0
request.onreadystatechange = function() {
console.log("事件--" + request.readyState);//打印每次触发事件时readyState的状态
console.log("服务器--" + request.status);
if(request.readyState === 2) {
console.log(request.getResponseHeader("Content-Type"));
}
if(request.readyState === 3) {
console.log(request.responseText);
}
if(request.readyState === 4 && request.status == 200) {
console.log(request.getResponseHeader("Content-Type"));
// console.log(JSON.parse(request.responseText));
console.log(request.responseText);
}
}
console.log("调用open之前--" + request.readyState);//0
console.log("服务器--" + request.status);
request.open("POST","./test.php",true);
console.log("调用open之后--" + request.readyState);//1
console.log("服务器--" + request.status);
request.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8");
console.log("设置头之后--" + request.readyState);//1
console.log("服务器--" + request.status);
request.send('aa="aadfd"');
console.log("调用send之后" + request.readyState);//1
console.log("服务器--" + request.status);
},false);
<?PHP
header("Content-Type:application/json");//设置响应头的,因为之前测试忘记了就没有删除,所以下面截图里才有application/json;这里没有必要有,只是我测试完了才看见。
echo $_POST['aa'];
?>

chrome截图:    IE截图

      你可以对照着这张截图看你就明白了,到底这个过程是怎么样的?其实你也不需要太了解这个过程,我们只对readyState等于4感兴趣。

可以发现在chrome,firefox,opera下的测试结果是,在你实例化XMLHttpRequest对象后,这个状态是0,当你调用了open()方法后这个状态变为了1,这时会触发一个readystatechange事件,你在设置头的时候,这个状态还是1,在你调用send()方法时,这个状态还是1,接下来就是靠readystatechange事件来监听了,它会被再触发三次,当这个状态变为2时,就接收到了响应头信息了,当变为3的时候就接收到响应主体了,当4的时候那就响应完成了。

IE稍微有点不同就是在在设置完头之后,还要触发一次readystatechange事件,其他的都相同

总结readyState值

常量 含义 
UNSENT 0 open()尚未调用
OPENED 1 open()已经调用
HEADERS_RECEIVED 2 接收到头信息
LOADING 3 接收到响应主体(内容)
DONE 4 响应完成

readystatechange事件就是在readyState属性值每次变化的时候触发。要是同步的就不需要监听这个事件。

接下来就说说XMLHttpRequest对象的这四个属性:responseText,responseXML,status,statusText,

  responseText:获得字符串形式的响应数据(只要不是xml格式的就用这个);

  responseXML:获得 XML 形式的响应数据;

  status:响应的Http状态;例如200.(这个与readyState的对应关系可以看上面的截图)

  statusText:响应的HTTP状态说明,例如ok,其实和status是一个意思,只不过是一个用数字说明,一个用文本说明罢了,200=>ok(这个只有readyState为2,3,4时有值);

最基础的都介绍完了,我们再来几个完整测试demo。

GET方式:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!-- <meta http-equiv="X-UA-Compatible" content="IE=edge"> -->
<title>php1</title>
<script type="text/javascript"> window.addEventListener("load",function() {
var btn = document.getElementById("btn");
var content = document.getElementById("content");
btn.addEventListener("click",function() {
var request = new XMLHttpRequest();
request.onreadystatechange = function() { if(request.readyState === 4 && request.status == 200) {
// console.log(JSON.parse(request.responseText));
content.innerHTML = request.responseText;
}
}
request.open("GET","./test.php",true);
// request.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8");
request.send(null);
}); },false);
</script>
</head>
<body>
<input type="button" value="点我" id="btn">
<h2>下面是点击后的内容:</h2>
<p id="content"></p>
</body>
</html>

php:

<?php
echo "hello!";
?>

点击前:

点击后

要是添加查询参数时,只需要修改open()方法的参数;

request.open("GET","./test.php?id=3&a=5",true);

php

<?php
echo "你给我的东西是:<br>";
echo 'id是:'.$_GET['id'],"<br>";
echo "a是:".$_GET['a'],"<br>";
if($_GET['id']) {
echo 'This is my respone!';
}
?>

点击后:

POST 方式:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!-- <meta http-equiv="X-UA-Compatible" content="IE=edge"> -->
<title>php1</title>
<script type="text/javascript"> window.addEventListener("load",function() {
var btn = document.getElementById("btn");
var text = document.getElementById("text");
var content = document.getElementById("content");
btn.addEventListener("click",function() {
var msg = "id=" + text.value;
console.log(msg);
var request = new XMLHttpRequest();
request.onreadystatechange = function() { if(request.readyState === 4 && request.status == 200) {
var obj = JSON.parse(request.responseText)
if(obj['name']){
content.innerHTML = 'name:' + obj['name'] + '<br>' + 'age:' + obj['age'];
} else {
content.innerHTML = "没有这个人的信息";
} }
}
request.open("POST","./test.php",true);
request.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8");
request.send(msg);
}); },false);
</script>
</head>
<body>
<label>请输入身份id:<input type="text" id="text"></label>
<input type="button" value="发送" id="btn">
<h2>下面是点击后的内容:</h2>
<p id="content"></p>
</body>
</html>

php代码:

<?php
header("Content-Type:application/json"); if($_POST['id'] == 001) {
echo '{"name":"wyl","age":22}';
} else {
echo '{}';
}
?>

输入:001前:

输入001,点击后:

输入其他字符点击后:

返回JSON格式的数据记得要用JSON.parse()解析;

POST的send()也可以不传递数据。

还有其他类型数据格式的请求或者响应的,以后有时间再介绍。

到此处最基本的东西应该就这些了。

00x2:XMLHttpRequest level 2:

  在HTML5来临的时候,w3c开始将这个XMLHttpRequest对象纳入标准中,因为以前就存在了这个对象,现在只是更新了,所以就叫2级XMLHttpRequest;

出现新的版本一定是老的版本有不足:

有以下几点不足:

1.以前只能传输文本数据,不能用来读取和上传二进制文件(比如图片);

2.接收和传递数据时,没有进度信息,只能知道是否传递完成;

3.不能进行跨域请求

新版本(XMLHttpRequest 2)的新特性:

1.可以设置HTTP的请求时限;

2.可以使用FormDate对象管理表单数据

3.可以上传文件

4.可以进行跨资源共享(跨域)CORS;

5.有更丰富的进度事件的API

要是介绍完,篇幅太长了,我自己都不看完,都看烦了,有空着再介绍;

参考资料:

犀牛书;红宝书;

http://www.cnblogs.com/skylar/p/ajaxCORS.html

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest

http://www.w3school.com.cn/ajax/ajax_intro.asp

http://javascript.ruanyifeng.com/bom/ajax.html

以上是自己结合了很多博客还有书籍总结的,仅代表个人对知识的理解和看法!如有不对的或者不准的地方,欢迎评论指正!

原文出处:浅谈JS之AJAX

浅谈JS之AJAX的更多相关文章

  1. 浅谈js分页的几种方法

    一个项目中必然会遇到分页这种需求的,分页可以使数据加载更合理,也让页面显示更美观,更有层次感!那么js分页到底如何实现呢?下面我就来讲一下三种循序渐进的方法 1.自己纯手写分页 更深入的去理解分页的意 ...

  2. 浅谈js拖拽

    本文来自网易云社区 作者:刘凌阳 前言 本文依据半年前本人的分享<浅谈js拖拽>撰写,算是一篇迟到的文章. 基本思路 虽然现在关于拖拽的组件库到处都是,HTML5也把拖放纳入了标准.但考虑 ...

  3. 浅谈JS中的闭包

    浅谈JS中的闭包 在介绍闭包之前,我先介绍点JS的基础知识,下面的基础知识会充分的帮助你理解闭包.那么接下来先看下变量的作用域. 变量的作用域 变量共有两种,一种为全局变量,一种为局部变量.那么全局变 ...

  4. 浅谈 js 正则字面量 与 new RegExp 执行效率

    原文:浅谈 js 正则字面量 与 new RegExp 执行效率 前几天谈了正则匹配 js 字符串的问题:<js 正则学习小记之匹配字符串> 和 <js 正则学习小记之匹配字符串优化 ...

  5. 浅谈 js 字符串之神奇的转义

    原文:浅谈 js 字符串之神奇的转义 字符串在js里是非常常用的,但是你真的了解它么?翻阅<MDN String>就可以了解它的常见用法了,开门见山的就让你了解了字符串是怎么回事. 'st ...

  6. 浅谈 js 正则之 test 方法

    原文:浅谈 js 正则之 test 方法 其实我很少用这个,所以之前一直没注意这个问题,自从落叶那厮写了个变态的测试我才去看了下这东西.先来看个东西吧. var re = /\d/; console. ...

  7. 浅谈 js 数字格式类型

    原文:浅谈 js 数字格式类型 很多人也许只知道 ,123.456,0xff 之类的数字格式.其实 js 格式还有很多数字格式类型,比如 1., .1 这样的,也有 .1e2 这样的. 可能有人说这是 ...

  8. 浅谈 js 语句块与标签

    原文:浅谈 js 语句块与标签 语句块是什么?其实就是用 {} 包裹的一些js代码而已,当然语句块不能独立作用域.可以详细参见这里<MDN block> 也许很多人第一印象 {} 不是对象 ...

  9. 浅谈 js 字符串 trim 方法之正则篇

    原文:浅谈 js 字符串 trim 方法之正则篇 关于 trim 其实没啥好说的,无非就是去除首位空格,对于现代浏览器来说只是简单的正则 /^\s+|\s+$/ 就可以搞定了.而且支持中文空格   等 ...

随机推荐

  1. QuickHit游戏

    一 项目需求 根据输入速率和正确率将玩家分为不同级别,级别越高,一次显示的字符数越多,玩家正确输入一次的得分也越高.如果玩家在规定时间内完成规定次数的输入,正确率达到规定要求,则玩家升级(为了简单起见 ...

  2. 分布式监控系统Zabbix-3.0.3-完整安装记录(2)-添加mysql监控

    Zabbix3.0 Server以后就自带了MySQL插件来监控mysql数据库的模板,只需要配置好agent客户端,然后在web端给主机增加模板就行了. 以下是公司线上的zabbix3.0环境下添加 ...

  3. 百度数据可视化图表套件echart实战

    最近我一直在做数据可视化的前端工作,我用的最多的绘图工具是d3.d3有点像photoshop,功能很强大,例子也很多,但是学习成本也不低,做项目是需要较大人力投入的.3月底由在亚马逊工作的同学介绍下使 ...

  4. redis 学习笔记(1)-编译、启动、停止

    一.下载.编译 redis是以源码方式发行的,先下载源码,然后在linux下编译 1.1 http://www.redis.io/download 先到这里下载Stable稳定版,目前最新版本是2.8 ...

  5. C# Memcache分布式缓存简单入门

    什么是Memcache?能做什么? 以下是百度的观点: memcache是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但目前被许多网站使用以提升网站的访问 ...

  6. dockerRegistry搭建

    docker registry安装: 官方仓库下载registry     pull镜像: fu@ubuntu:~$ sudo docker pull registry    运行镜像 : sudo ...

  7. Don’t Use Accessor Methods in Initializer Methods and dealloc 【初始化和dealloc方法中不要调用属性的存取方法,而要直接调用 _实例变量】

    1.问题:    在dealloc方法中使用[self.xxx release]和[xxx release]的区别? 用Xcode的Analyze分析我的Project,会列出一堆如下的提示:Inco ...

  8. LCIS

    传送门 http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=726&pid=1003 分析:这道题依然是动态 ...

  9. 微信小程序之明源商城系列-01-商城介绍及开发准备

    1,效果展示 数据来自于写的一个小爬虫爬了明源商城部分的数据.由于价格的保密性,下列产品价格和真实的都不同. 1.1 主页及开发文件结构 1.2  产品的详细页面 1.2  产品分类页面 1.3 产品 ...

  10. Spring-IOC-BeanFactory

    BeanFactory BeanFactory 是 Spring 的“心脏”.它就是 Spring IoC 容器的真面目.Spring 使用 BeanFactory 来实例化.配置和管理 Bean.但 ...