creeperyang / blog

前端博客,关注基础知识和性能优化。
MIT License
2.63k stars 211 forks source link

Ajax和Http协议浅谈 #11

Closed creeperyang closed 6 years ago

creeperyang commented 9 years ago

题目很大,主要是相关知识点很多,可能涉及的面也很广。

写这个issue的用意:梳理ajax用法,前后台交互,API设计,HTTP协议等等的知识点,温故知新。在这里不尝试阐述的面面具到,但重点的地方还是会尽可能解释清楚。

creeperyang commented 9 years ago

1. Ajax和Web2.0

Ajax(Asynchronous JavaScript and XML),是一套web开发技术,用于浏览器端创建异步web应用。有了Ajax,web应用可以在后台(in the background)向服务器发送数据,或者从服务器获取数据,而不用影响现存页面(比如刷新)。

一般情况下,我们使用XMLHttpRequest对象来获取数据。Ajax名字中的XML也不是必须的,Request请求也不一定是异步的。

历史

  1. 在1990年代,几乎所有网站都是基于html页面,每个交互都需要完全重新加载页面。用户体验差,低效,浪费带宽。
  2. 1996,iframe标签被IE引入,用来异步加载/获取内容。
  3. 1999,IE5创建XMLHTTP ActiveX,其它浏览器跟进并以XMLHttpRequestJS对象的形式采用。到IE7,微软采用了XMLHttpRequest(IE系列保留XMLHTTP ActiveX)。
  4. 2004,谷歌大量使用符合标准,跨浏览器的Ajax,开发了Gmail和Google Maps(2005),标志Web2.0的到来。
  5. 2005-02-18,Jesse James Garrett在文章"Ajax: A New Approach to Web Applications"中首次公布术语Ajax。
  6. 2006-04-05,W3C标准化了XMLHttpRequest
creeperyang commented 9 years ago

2.XMLHttpRequestjQuery.ajax

XMLHttpRequest就是前端向服务器发起异步请求的浏览器API。jQuery.ajaxjQuery库对XMLHttpRequest以及jsonp的统一包装。这一段主要以XMLHttpRequest来讲一讲发送/接收数据的处理。

处理响应

响应数据是 textual data

var req = new XMLHttpRequest();
req.addEventListener('load', console.log.bind(console, '[req]'));
req.open('GET', '/');
req.send();

// req.responseText/responseXML

一般情况下,我们通过responseText属性来获取后台响应的文本数据(如果后台响应XML,可以通过responseXML获取)。

响应数据是 binary data

XMLHttpRequest Level 2:

var oReq = new XMLHttpRequest();

oReq.onload = function(e) {
  var arraybuffer = oReq.response; // not responseText
  /* ... */
}
oReq.open("GET", url);
oReq.responseType = "arraybuffer";
oReq.send();

XMLHttpRequest Level 1:

var oReq = new XMLHttpRequest();
oReq.open("GET", url);
// retrieve data unprocessed as a binary string
oReq.overrideMimeType("text/plain; charset=x-user-defined");

设置HTTP头和处理要发送的数据

HTTP method

oReq.open(method, url, ...) method可以是"GET", "POST", "PUT", "DELETE"等等,其中以"GET", "POST"最常用。

function getHeaderTime () {
  alert(this.getResponseHeader("Last-Modified"));  /* A valid GMTString date or null */
}

var oReq = new XMLHttpRequest();
oReq.open("HEAD" /* use HEAD if you only need the headers! */, "yourpage.html");
oReq.onload = getHeaderTime;
oReq.send();
GET

"GET"用来获取后台数据,无法通过xhr.send(data)向后台传送数据。有数据的话一般编码后以query形式添加到url上。

HEAD

"HEAD"与"GET"相同,但要求服务器响应中不要有HTTP message body。所以不需要/不应该向后台传数据。