先引入一下HTTP的请求过程还有介绍一下运行环境php
一个完整的HTTP请求过程,一般有下面7个步骤:html
创建TCP链接
Web浏览器向Web服务器发送请求命令
Web浏览器发送请求头信息
Web服务器- 应答
Web服务器- 发送应答头信息
Web服务器- 向浏览器发送数据
Web服务器- 关闭TCP链接web
Ajax必须在服务器环境下才能正常使用:ajax
可使用WampServer程序数据库
AJAX简介编程
Ajax(Asynchronous JavaScript and XML 异步的JavaScript与XML)是一种与服务器交换数据无需刷新网页的技术,最先由Google公司在谷歌地图里使用,并迅速风靡。json
它是一系列web开发技术的集合,是一种使用不少的web技术,能在在客户端开发异步web应用。利用Ajax,web应用能够异步的发送数据获取数据,而不干扰现有页面的显示和行为。经过解耦数据接口层和展示层,Ajax容许web页面或者其余扩展的web应用动态的改变数据而不用从新加载整个页面。实现一般选择JSON代替XML,由于JSON更接近JavaScript,操做更加方便。segmentfault
Ajax不是一种技术,是一组技术。HTML和CSS用来组合标记和样式信息。用户能够利用js访问DOM对象负责动态展现。js和XMLHttpRequest对象提供一种浏览器和服务端异步互换数据的方法从而避免整个页面加载。跨域
关于AJAX的历史浏览器
在90年代中期,许多web站点彻底基于html页面。每一个用户行为都须要从服务端从新加载页面。这个过程很不方便,影响用户体验:全部的页面内容消失,而后又出现。每次由于小部分改动须要浏览器从新加载页面,全部内容都必须从新获取,甚至只有不多的信息改变。这会额外增长服务端负载,浪费带宽,影响性能。
在1996年,IE引入了iframe标签来异步加载获取内容。
在1998年,微软的邮件组团队利用客户端脚本实现了第一个XMLHTTP组件。
在1999年,微软在IE的默认页面使用iframe技术动态更新新闻故事和股票行情,而且在IE5中建立了XMLHTTP ActiveX组件,这个技术随后被Mozilla,Safari,Opera以及其余浏览器采用,做为XMLHttpRequest js对象。微软在IE7中采用了原生的XMLHttpRequest模块。IE仍然支持ActiveX版本,可是在Edge中不支持了。这种技术的使用在当时至关不明朗直到出如今大规模线上应用中,好比Outlook Web App (2000)和Oddpost。
谷歌在Gmail(2004)和Google Maps(2005)中广发部署了符合标准的跨浏览器Ajax。在2004年10月Kayak.com的公测版本是首次大规模电子商务网站使用了他们当时称为"the xml htpp thing"的技术。
Jesse James Garrett在2005年2月18号发表的一篇题为"Ajax: A New Approach to Web Applications"的论文中,基于Google 页面中使用的技术,公开阐明了"Ajax"这个术语。
在2006年4月5号,W3C发表了第一个关于XMLHttpRequest对象的草案,尝试创建一个官方的Web标准。关于XMLHttpRequest对象最新的草案是在2014年1月30号发布的。
技术集
Ajax术语已经变成了web应用用来与服务端在幕后交流不打断页面当前状态而使用的一组技术的表明。在Jesse James Garrett的论文里创造的Ajax术语包括如下技术:
展示层的HTML(或者XHTML)和CSS
动态显示和与数据交互的DOM对象
为了交换数据的JOSN或者XML,为了操纵数据的XSLT
为了异步通讯的XMLHttpRequest对象
把这些技术整合起来的JavaScript
工做原理
传统Web应用模型与使用Ajax的Web应用模型对比
传统方式: 客户端发起请求--等待-->服务器端处理---等待-->响应-->页面载入 (请求错误时所有从新载入).
使用AJAX: 客户端发起请求--->服务器端处理--->响应--->页面载入(填写时,即时更新,部分返回).
编写AJAX
全部现代浏览器(IE7+、Firefox、Chrome、Safari 以及 Opera)均内建 XMLHttpRequest
对象。
Ajax编写步骤
1.建立Ajax对象
2.链接服务器
3.发送请求
4.接受返回
建立Ajax对象:
//IE6以上 var oAjax = new XMLHttpRequest(); //IE6 var oAjax =new ActiveXObject("Microsoft.XMLHTTP")
链接服务器
open(method,url,async); open(发送请求方法"GET/POST" ,(请求地址"文件名") ,是否异步传输) 例: request.open("GET","get.json",true);
Ajax天生就是工做在异步模式的(异步为true,同步false)
同步和异步
同步是指:发送方发出数据后,等接收方发回响应之后才发下一个数据包的通信方式。
异步是指:发送方发出数据后,不等接收方发回响应,接着发送下个数据包的通信方式。
发送请求send()
send(string)
在使用GET方式请求时无需填写参数
在使用POST方式时参数表明着向服务器发送的数据
//完整的GET请求 var oAjax = new XMLHttpRequest();//建立Ajax对象 oAjax.open("GET","create.php",true);//链接服务器 oAjax.send();//发送请求 //完整的POST发送请求 var oAjax = new XMLHttpRequest();//建立 oAjax.open("POST","create.php",true);//"POST" oAjax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");//设置HTTP头信息.必须在open与send之间,不然出现异常. oAjax.send("name=陈二狗&sex=男");//发送给服务器的内容
GET 仍是 POST?
与 POST 相比,GET 更简单也更快,而且在大部分状况下都能用。
然而,在如下状况中,请使用 POST 请求:
没法使用缓存文件(更新服务器上的文件或数据库)
向服务器发送大量数据(POST 没有数据量限制)
发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠
接收返回信息
oAjax.onreadystatechange = function(){ //当请求状态改变时要调用的事件处理器 alert(oAjax.readystate); }
只要readyState
属性的值发生变化时,便会触发一次readyStatechange
事件。能够利用这个事件来检测每次状态变化后readyState的值。一般,咱们只对readyState值为4的阶段感兴趣,由于这时全部数据都已经就绪,不过,必须在调用open()
以前指定onreadystatechange
事件处理程序才能确保跨浏览器兼容性。
下面来看一个例子:
var xhr = createXHR(); xhr.onreadystatechange = function () { if (xhr.readyState == 4) { if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) { alert(xhr.statusText); } else { alert("Request was unsuccessful: " + xhr.status); } } }; xhr.open("get", "example.txt", true); xhr.send(null);
XMLHttpRequest
这个对象的属性:
onreadystatechange 每次状态改变所触发事件的事件处理程序。
responseText 从服务器进程返回数据的字符串形式。
responseXML 从服务器进程返回的DOM兼容的文档数据对象。
status 从服务器返回的数字代码,好比常见的404(未找到)和200(已就绪)
status Text 伴随状态码的字符串信息
当XHR对象把一个HTTP请求发送到服务器的过程当中会经历几个状态,直到请求被处理,而后才接收一个回应。readyState
就是XHR请求的状态属性,它自己有5个属性值:
0(未初始化)尚未调用open()方法 1(载入)已调用send()方法,正在发送请求 2(载入完成)send()方法完成,已收到所有响应内容 3(解析)正在解析响应内容 4(完成)响应内容解析完成,能够再客户端使用了
status和statusText
statusText
是响应返回的文本信息,仅当readyState
值为3或4的时候才能使用。当readyState
为其它值时视图存取statusText
属性将引起异常。
XHR的方法
方法 | 描述 |
---|---|
abort() | 致使当前正在执行的请求被取消 |
getAllResponseHeaders() | 返回包含全部响应头的名称和值的单个字符 |
getResponseHeader(name) | 返回响应头中指定的名称和值 |
open(method,url,async,username,pwd) | 设置HTTP方法(get或post)等 |
send(content) | 发出带有指定主体内容的请求 |
setRequestHeader(name,value) | 使用指定的名称和值设置请求头 |
//基本完整的一个Ajax请求 var request = new XMLHttpRequest(); request.open("GET","get.json",true); request.onreadystatechange = function () { if (request.readyState === 4) { if (request.status === 200) { //响应成功,作一些事情 } else { //响应失败,作一些事情 } } };
使用函数简单的封装一个get请求
/** * 一个简单的异步get请求 * @param {String} url 请求地址,文件名 * @param {Function} fnSucc 请求成功时执行的函数,形参为为获取的字符串值. * @param {Function} fnFaild 请求失败执行的函数,可选参数 */ function get(url, fnSucc, fnFaild) { //1.建立ajax对象 var oAjax = null //此处必须须要使用window.的方式,表示为window对象的一个属性.不存在是值为undefined,进入else/若直接使用XMLHttpRequest在不支持的状况下会报错 if (window.XMLHttpRequest) { oAjax = new XMLHttpRequest(); } else { //IE6以上,如今应该不须要考虑IE6了 oAjax = new ActiveXObject("Microsoft.XMLHTTP"); } //2.链接服务器 //open(方法,url,是否异步) oAjax.open("GET", url, true); //3.发送请求 oAjax.send(); //4.接收返回 //OnRedayStateChange事件 oAjax.onreadystatechange = function () { if (oAjax.readyState === 4) { if (oAjax.status === 200) { fnSucc(oAjax.responseText); } else { if (fnFaild) { fnFaild(); } } } }; }
这样的封装还不够,缘由以下:
目前方法只能使用get请求,而不能使用post请求,而在用户注册时必须使用POST,由于POST,如今不够完整。
目前请求参数只能直接写在url里,不利于动态获取数据,应该使用参数解析的方式,便于使用。
get请求方式请求缓存问题。
封装以下:
/** * AJAX函数封装 * @param {string} url 请求地址(必须) * @param {object} options 发送请求的选项参数 * @config {string} [options.type] 请求发送的类型。默认为GET。 * @config {Object} [options.data] 须要发送的数据。 * @config {Function} [options.onsuccess] 请求成功时触发,function(oAjax.responseText, oAjax)。(必须) * @config {Function} [options.onfail] 请求失败时触发,function(oAjax)。(oAJax为XMLHttpRequest对象) * *@returns {XMLHttpRequest} 发送请求的XMLHttpRequest对象 */ function AJAX(url, options) { //1.建立ajax对象 var oAjax = null; /** * 此处必须须要使用window.的方式,表示为window对象的一个属性.不存在时值为undefined,进入else * 若直接使用XMLHttpRequest,在不支持的状况下会报错 **/ if (window.XMLHttpRequest) { //IE6以上 oAjax = new XMLHttpRequest(); } else { oAjax = new ActiveXObject("Microsoft.XMLHTTP"); } //2.链接服务器 //open(方法,url,是否异步) var param = ""; //请求参数。 //只有data存在,且为对象使才执行 var data = options.data ? options.data : -1; //缓存data if (typeof (data) === "object") { for (var key in data) { //请求参数拼接 if (data.hasOwnProperty(key)) { param += key + "=" + data[key] + "&"; } } param.replace(/&$/, ""); } else { param = "timestamp=" + new Date().getTime(); } //3.发送请求 var type = options.type ? options.type.toUpperCase() : "GET"; if (type === "GET") { oAjax.open("GET", url + "?" + param, true); oAjax.send(); } else { oAjax.open("POST", url, true); oAjax.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); oAjax.send(param); } //4.接收返回 //OnRedayStateChange事件 oAjax.onreadystatechange = function () { if (oAjax.readyState === 4) { if (oAjax.status === 200) { //请求成功。形参为获取到的字符串形式的响应数据 options.onsuccess(oAjax.responseText, oAjax); } else { //先判断是否存在请求失败函数 //存在时,形参为XMLHttpRequest对象,便于进行错误进行处理 if (options.onfail) { options.onfail(oAjax); } } } }; return oAjax;//发送请求的XMLHttpRequest对象 }
options是一个对象,里面能够包括的参数为:
type: post或者get,能够有一个默认值
data: 发送的数据,为一个键值对象或者为一个用&链接的赋值字符串
onsuccess: 成功时的调用函数
onfail: 失败时的调用函数
应用优点
· AJAX不是一种新的编程语言,而是一种用于建立更好更快以及交互性更强的Web应用程序的技术。
· 使用Javascript向服务器提出请求并处理响应而不阻塞用户!核心对象XMLHTTPRequest。经过这个对象,您的 JavaScript 可在不重载页面的状况与Web服务器交换数据,即在不须要刷新页面的状况下,就能够产生局部刷新的效果。
· AJAX 在浏览器与 Web 服务器之间使用异步数据传输(HTTP 请求),这样就可以使网页从服务器请求少许的信息,而不是整个页面。
· AJAX 可以使因特网应用程序更小、更快,更友好。
· AJAX 是一种独立于 Web 服务器软件的浏览器技术。
· AJAX 基于下列 Web 标准:
JavaScriptXMLHTMLCSS在 AJAX 中使用的 Web 标准已被良好定义,并被全部的主流浏览器支持。AJAX 应用程序独立于浏览器和平台。
Web 应用程序较桌面应用程序有诸多优点;它们可以涉及广大的用户,它们更易安装及维护,也更易开发。
不过,因特网应用程序并不像传统的桌面应用程序那样完善且友好。
经过 AJAX,因特网应用程序能够变得更完善,更友好。
弊端
· 若是用户浏览器不支持JavaScript或者XMLHttpRequest,或者禁用这种功能,则不能正常使用依赖Ajax的页面。简单设备(例如智能手机,pad)可能不支持须要的这些技术。让用户使用这种功能的惟一方法是回退到没有JavaScript方法。能够同经过确保连接表单正确解析而不是仅仅依赖Ajax来实现相关功能。
· 一样的,一些使用Ajax的Web应用对屏幕阅读技术不友好,例如JAWS。WAI-ARIA标准提供了一种方法在这种状况下提供提示。
· 屏幕阅读器可使用Ajax,可是也可能不能正确的读取动态产生的内容。
· 同源策略阻止了一些Ajax技术跨域使用,尽管W3C有关于XMLHttpRequest对象的草案容许这个功能。经过使用一个特别的跨域通道例如页面中的iframe或者使用JSONP能够跨过这种安全限制。
· 异步的回调编程可能致使负责的代码难以维护,调试和测试。
· 由于Ajax的异步特性,客户端发送接收到每块数据都发生在专门为改事件创建的链接上。这就为每一个行为增长一种须要,那就是客户端必须轮询服务端,而不是监听,这就会致使额外开销。这种开销会致使Ajax应用有更高的延迟相比于利用websocket技术获取数据。
· 在非HTML5浏览器中,使用Ajax请求建立的动态页面不能自动的注册到浏览器的历史记录中,因此在点击浏览器"回退"按钮时,浏览器不会回到Ajax发生以前的状态,可是会回退到上次访问的页面。这种在页面之间导航而不是在页面状态之间导航的行为可能不是想要的,可是若是须要追踪页面状态,那么对于非HTML5的浏览器一个变通的方案就是使用非透明的iframe触发浏览器历史记录的改变。另外一个变通方法就是利用Ajax技术更改URL的片断标识符(URL中在"#"以后的部分)。HTML5提供了一个扩展的API标准来操做浏览器历史记录。
· 动态web页面更新致使很难记标签,返回应用的特性状态。这种问题的解决办法也是存在的,也是利用URL的片断标识符。HTML5提供了解决上面问题的方法。
· 因为Ajax应用的特性,动态页面更新可能会打断用户交互,特别是当网络链接很慢或者不可能的时候。例如,编辑一个搜索框可能会触发一个服务端查询,可是用户可能不知道查询结束时会弹出一个框,若是此时网络很慢,弹窗可能会在一个不恰当的时候弹出,当用户已经开始处理其余的事情时。
· 除了Google,大多数网络爬虫不能执行js代码,因此为了被搜索引擎收录,Web应用必须为那些经过Ajax获取内容的页面提供一个备选页面。
虽然AJAX存在不少弊端,可是随着技术的发展,不少弊端都可以很好地来避免。
参考: