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. iOS通知

    链接: IOS之推送通知(本地推送和远程推送) iOS 10推送通知开发 活久见的重构 - iOS 10 UserNotifications 框架解析 iOS10全新推送功能的实现

  2. 错误提示:LINK : fatal error LNK1123: failure during conversion to COFF: file invalid or corrupt 的解决方法

    最近在win7 系统下,打算利用 cmake 生成项目文件,然后用vs2010进行编译.但是在cmake的时候出现错误弹窗:

  3. 关于Linux与Windows的区别的文章

    你从来只用过Windows,从来没接触过UNIX,只知道把一个文件拽来拽去,只知道硬盘就是C: D: E:却从来没有研究过分区表,也许 会用VC编个程序,很习惯它的集成环境.... 有一天,不管什么原 ...

  4. 用html5 canvas和JS写个数独游戏

    为啥要写这个游戏? 因为我儿子二年级数字下册最后一章讲到了数独.他想玩儿. 因为我也想玩有提示功能的数独. 因为我也正想决定要把HTML5和JS搞搞熟.熟悉一个编程平台,最好的办法,就是了解其原理与思 ...

  5. linux免交互登陆远程主机并执行命令(密钥对和Expect)

    原文章摘自:http://lizhenliang.blog.51cto.com/7876557/1607723/ Linux下实现免交互登陆一般有两种: 1. SSH无密码认证方式 客户端使用ssh- ...

  6. Neural Style学习3——操作

    Basic usage: th neural_style.lua -style_image <image.jpg> -content_image <image.jpg> Ope ...

  7. 菜鸟初识python request属性及方法说明

    if  request.REQUEST.has_key('键值'): HttpRequest对象的属性 参考: 表 H-1. HttpRequest对象的属性 属性 描述 path 表示提交请求页面完 ...

  8. Git从入门到学会

    Git简介 Git是什么? Git和SVN一样都是一种高效的管理代码的系统. Git是目前世界上最先进的分布式版本控制系统(没有之一). 创建版本库 什么是版本库呢?版本库又名仓库,英文名reposi ...

  9. bzoj 1305 dance跳舞

    最大流. 首先二分答案,问题转化为x首舞曲是否可行. 考虑建图,对每个人建立三个点,分别表示全体,喜欢和不喜欢. 源点向每个男生全体点连一条容量为x的边. 每个男生整体点向喜欢点连一条容量为正无穷的边 ...

  10. Django简单的数据库操作

    当然,本篇的前提是你已经配置好了相关的环境,这里就不详细介绍. 一. 在settings.py文件中设置数据库属性. 如下: DATABASES = { 'default': { 'ENGINE': ...