Skip to content

Latest commit

 

History

History
213 lines (169 loc) · 4.93 KB

ajax.md

File metadata and controls

213 lines (169 loc) · 4.93 KB

##ajax

XMLHttpRequest对象

function createXHR() {
  return (function f() {
    if(typeof XMLHttpRequest !== 'undefined') {
     return new XMLHttpRequest();
   }
   
   if(typeof ActiveXObject !== 'undefined') {
     if(f.activeXObject !== 'string'){
     	var versions = ['MSXML2.XMLHttp.6.0', 'MSXML2.XMLHttp.3.0', 'MSXML2.XMLHttp'];
     	for(var i = 0, ii = versions.length; i < ii; i++) {
          try {
          	new ActiveXObject(versions[i]);
          	f.activeXObject = versions[i];
          	break;
          } catch(e) {

          }
     	}
     	return new ActiveXObject(f.activeXObject);
     }
   }

   throw new Error('no xhr');
  })();
}

###XHR的用法

xhr.open(method, url, bool)

  • method表示请求方法,get,post。
  • url表示请求地址。
  • bool为true时发起异步请求,为false时同步请求。

xhr.send(data)表示请求主体发送数据,如果不发送,则必须指定为null。

###响应

  • responseText作为响应的文本。
  • responseXML 响应类型为"text/xml"或"application/xml",这个属性将保存响应数据的XML DOM文档。
  • status 保存响应的状态码。
  • statusText http状态说明。

###响应阶段

  • 同步发送。

  • 异步请求

xhr状态

  • 0: 未初始化。尚未调用open方法。
  • 1: 启动。调用open方法,但没有调用send。
  • 2: 发送数据。调用send,但没有接到响应数据。
  • 3: 接收。接收部分数据,但没有发送完。
  • 4: 完成。接收全部数据。客户端可以使用。
function request(o) {
  var xhr = null;
  try {
    xhr = createXHR();
  } catch(e) {
    throw new Error('create XHR error');
  }
  
  xhr.onreadystatechange = function() {
    if(xhr.readyState === 4) {
      if((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
      	o.success(xhr.responseText);
      } else {
      	o.error(xhr.statusText);
      }
    } 
  } 

  xhr.open(o.method, o.ourl, o.async);
  xhr.send(o.data);
}

xhr.onreadystatechange的callback没有使用this代替xhr,部分浏览错误.

xhr.abort()在接受响应之前停止请求。

xhr.setRequestHeader("myHeader", "myValue");

setRequestHeader不建议设置http的请求头,在调用时必须在open之后,send之前。

###XMLHttpRequest2

#####FormData序列化表单和创建和表单一样的数据

var formdata = new FormData();
formdata.append("name", "yanglei");
var form = document.forms.form;
var formdata = new FormData(form);

###跨域技术

  • 图像ping
var img = new Image();
img.onload = img.onerror = function() {
  console.log('Done');
};

img.url = url;
  • JSONP跨域,动态脚本技术
function handleResponse(response) {
	//todo
}

var script = document.createElement('script');
script.src = url + '?callback=' + handleResponse;
document.body.appendChild(script);

  判断是否加载完毕。

 script.onload = script.onreadystatechange = function() {
   if(!this.readystate || this.readystate === 'loaded' || this.readystate === 'complete') {
      handleResponse(value);
   }
 }
  var ifr = document.createElement('iframe');
  ifr.src = 'http://hhh.a.com/hhh.html';
  ifr.style.display = 'none';
  document.body.appendChild(ifr);
  ifr.onload = function() {
    //操作http://hhh.a.com/hhh.html页面
  }
  • window.name'实现跨域,此技术核心是url改变,但window.name`不变。 举个栗子,http://a.com/a.html和http://b.com/b.html通信。 在a.html中;

    "use strict";
    var ifr = document.createElement('iframe');
    var state = 0, data;
    ifr.style.display = 'none';
    ifr.onload = function() {
      if(state == 0) {
        state = 1;
        ifr.contentWindow.location = 'http://a.com/proxy.html';
      } else {
        data = ifr.contentWindow.name;
        alter(data);
      }
    }
    document.body/appendChild(ifr);

    在b.html中;

    "use strict";
    <script type="text/javascript">
      window.name = data    //data;
    </script>

    最后销毁这个iframe,确保安全。

    "use strict";
    ifr.contentWindow.innerHTML = '';
    ifr.contentWindow.close();
    document.body.removeChild(ifr);
  • `postMessage'实现跨域。XDM夸文档消息传递。

 "use strcit";
 var ifr = document.getElementById('otherWindow').contentWinwow;
 ifr.postMessage(data, url);
 "use strcit";
 function callback(e) {
   if(e.origin === url) { 
      alter(e.data);
   }
 }

 window.addEventListener('message',callback,false);
  • iframelocation.hash实现跨域, 此技术利用location.hash传递值,有限制。

  • flash实现跨越。