• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    简单介绍不用库(框架)自己写ajax

    平常会使用ajax来请求数据,加载一个库(框架),或许仅仅maybe就使用了它的ajax部分。

      写个ajax,一来可以经历一下处理问题的过程,提升技术能力,二来工作中有时真的用不着这么大的一个库(框架),用自己写的,何乐不为呢。

      先来看看流行的jQuery是怎样调用ajax的

    $.ajax({
      url:    'test.php',   //发送请求的URL字符串
      type:    'GET',     //发送方式 
      dataType:  'json',     //预期服务器返回的数据类型 xml, html, text, json, jsonp, script
      data:    'k=vk=v',   //发送的数据 
      async:   true,      //异步请求 
      cache:   false,     //缓存 
      timeout:  5000,      //超时时间 毫秒
      beforeSend: function(){},  //请求之前
      error:   function(){},  //请求出错时
      success:  function(){},  //请求成功时
      complete:  function(){}  //请求完成之后(不论成功或失败)
    });

       这样的调用是不是很舒适、方便,如果感觉舒适那自己动手写也参照这种设计方式,不用太复杂,满足所需就好。

      先了解ajax的基础知识

      XMLHttpRequest 对象

      XMLHttpRequest对象是ajax的核心,通过XMLHttpRequest对象来向服务器发异步请求,从服务器获得数据,所有现代浏览器(IE7+、Firefox、Chrome、Safari、Opera)均支持 XMLHttpRequest 对象(IE5 和 IE6 使用 ActiveXObject)。  

      创建一个兼容的XMLHttpRequest对象

    var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');

       向服务器发送请求

    xhr.open(method,url,async);
        //method:请求的类型;GET 或 POST
        //url:请求的URL
        //async:true(异步)或 false(同步)
    xhr.send(string);
        //将请求发送到服务器
        //string:仅用于 POST 请求
    //GET 比 POST 请求方式更简单也更快,并且在大部分情况下都能用
    //在以下情况中,请使用 POST 请求:
        //无法使用缓存文件(更新服务器上的文件或数据库)
        //向服务器发送大量数据(POST 没有数据量限制)
        //发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠

      服务器响应

      使用 XMLHttpRequest 对象的 responseText 或 responseXML 属性获得来自服务器的响应。

        如果来自服务器的响应是 XML,而且需要作为 XML 对象进行解析,请使用 responseXML 属性。

        如果来自服务器的响应并非 XML,请使用 responseText 属性,responseText 属性返回字符串形式的响应。

      onreadystatechange 事件

      当请求被发送到服务器时,我们需要执行一些基于响应的任务。每当 readyState 改变时,就会触发 onreadystatechange 事件。readyState 属性存有 XMLHttpRequest 的状态信息。

       XMLHttpRequest 对象的三个重要的属性:

        onreadystatechange  //存储函数(或函数名),每当 readyState 属性改变时,就会调用该函数

        readyState  //存有 XMLHttpRequest 的状态, 从 0 到 4 发生变化     

    0: 请求未初始化
    1: 服务器连接已建立
    2: 请求已接收
    3: 请求处理中
    4: 请求已完成,且响应已就绪

        status  //200: "OK", 404: 未找到页面

      在 onreadystatechange 事件中,我们规定当服务器响应已做好被处理的准备时所执行的任务, 当 readyState等于4 且 status为200 时,表示响应已就绪。

    xhr.onreadystatechange = function(){
      if( xhr.readyState == 4  xhr.status == 200 ){
        //准备就绪 可以处理返回的 xhr.responseText 或者 xhr.responseXML 
      }
    };

       一个简单的ajax请求如下:

    var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
    xhr.onreadystatechange = function(){
      if( xhr.readyState == 4  xhr.status == 200 ){
        //准备就绪 可以处理返回的 xhr.responseText 或者 xhr.responseXML 
      }
    };
    xhr.open(method,url,async);
    xhr.send(string);

       补充:1. 发送GET请求时可能得到的是缓存的结果,为了避免这种情况,可以向URL 添加一个唯一的 ID,时间戳。2. 如果需要像HTML表单那样 POST 数据,使用 setRequestHeader() 来添加 HTTP 头。然后在 send() 方法中发送数据。

    url += (url.indexOf('?')  0 ? '?' : '') + '_='+ (+new Date());
    xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');

      开始写自己的ajax

      先写一个基本的,定义好各种参数选项,供参考

    var $ = (function(){
      //辅助函数 序列化参数 
      function param(data){
        //..  
      }
     
      function ajax(opts){
        var _opts = {
          url    : '/',       //发送请求URL地址
          type    : 'GET',      //发送请求的方式 GET(默认), POST
          dataType  : '',        //预期服务器返回的数据类型 xml, html, text, json, jsonp, script
          data    : null,       //发送的数据 'key=valuekey=value', {key:value,key:value}  
          async   : true,       //异步请求 ture(默认异步), false
          cache   : true,       //缓存 ture(默认缓存), false 
          timeout  : 5,        //超时时间 默认5秒
          load    : function(){},   //请求加载中
          error   : function(){},   //请求出错时
          success  : function(){},   //请求成功时
          complete  : function(){}   //请求完成之后(不论成功或失败)
        }, aborted = false, key,
        xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
        for(key in opts) _opts[key] = opts[key];        
         
        /*
        if(_opts.dataType.toLowerCase() === 'script'){
          //..
        }
        if(_opts.dataType.toLowerCase() === 'jsonp'){
          //..
        }
        */
        if(_opts.type.toUpperCase() === 'GET'){
          if(param(_opts.data) !== ''){
            _opts.url += (_opts.url.indexOf('?')  0 ? '?' : '') + param(_opts.data);
          }
          !_opts.cache  ( _opts.url += (_opts.url.indexOf('?')  0 ? '?' : '') + '_='+(+new Date()) );
        }
     
        function checkTimeout(){
          if(xhr.readyState !== 4){
            aborted = true;
            xhr.abort();
          }
        }
        setTimeout(checkTimeout, _opts.timeout*1000);
         
        xhr.onreadystatechange = function(){
          if( xhr.readyState !== 4 ) _opts.load  _opts.load(xhr);
          if( xhr.readyState === 4 ){
            var s = xhr.status, xhrdata;
            if( !aborted  ((s >= 200  s  300) || s === 304) ){
              switch(_opts.dataType.toLowerCase()){
                case 'xml':
                  xhrdata = xhr.responseXML;
                break;
                case 'json':
                  xhrdata = window.JSON  window.JSON.parse ? JSON.parse(xhr.responseText) : eval('(' + xhr.responseText + ')');
                break;
                default:
                  xhrdata = xhr.responseText;
              }
              _opts.success  _opts.success(xhrdata,xhr);
            }else{
              _opts.error  _opts.error(xhr);
            }
            _opts.complete  _opts.complete(xhr);
          }
        };   
        xhr.open(_opts.type,_opts.url,_opts.async);
        if(_opts.type.toUpperCase() === 'POST'){
          xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
        }
        xhr.send(_opts.type.toUpperCase() === 'GET' ? null : param(_opts.data));
      }
      return {
        ajax: ajax
      }
    })();

       定义好了参数选项,来分析一下。其中 dataType 是整个ajax的重点,代码的简单或者复杂都在它了。

      在这里dataType为预期服务器返回的数据类型:xml, html, text, json, jsonp, script

      1. 为xml时,来自服务器的响应是XML,使用 responseXML 属性获取返回的数据

      2. 为html、text、json时,使用 responseText 属性获取返回的数据

          a. 为html时,返回纯文本HTML信息,其中包含的script标签是否要在插入dom时执行 ( 代码复杂度+3 )

          b. 为json时,  返回JSON数据,要安全、要便捷、要兼容  ( 代码复杂度+2 )

      3. 为jsonp时,一般跨域才用它,不用原来的ajax请求了,用创建script法( 代码复杂度+2 )

      4. 为script时:  要跨域时,不用原来的ajax请求了,用创建script法( 代码复杂度+1 ); 不跨域,返回纯文本JavaScript代码, 使用 responseText 属性获取返回的数据 ( 代码复杂度+1 )

      其中,在html片段中的script标签、jsonp、script,都要用到创建script标签的方式。

      处理dataType为json

    xhrdata = window.JSON window.JSON.parse ? JSON.parse(xhr.responseText) : eval('(' + xhr.responseText + ')');

      这是最简单的处理方式了,要JSON兼容,可以用json2.js。

      处理dataType为jsonp

      jsonp是要通过script标签来请求跨域的,先了解下流程:

      这上图中 a.html中请求了 http://www.b.com/b.php?callback=add  (在ajax程序中请求url就是这个链接),在b.php中读取了传过来的参数 callback=add  根据获取到的参数值(值为add),以JS语法生成了函数名,并把json数据作为参数传入了这个函数,返回以JS语法生成的文档给a.html,a.html解析并执行返回的JS文档,调用了定义好的add函数。

       在程序中一般采用更通用的方式去调用,比如下面这个广泛使用的loadJS函数:

    function loadJS(url, callback) {
      var doc = document, script = doc.createElement('script'), body = doc.getElementsByTagName('body')[0];
      script.type = 'text/javascript';
      if (script.readyState) { 
        script.onreadystatechange = function() {
          if (script.readyState == 'loaded' || script.readyState == 'complete') {
            script.onreadystatechange = null;
            callback  callback();
          }
        };
      } else { 
        script.onload = function() {
          callback  callback();
        };
      }
      script.src = url;
      body.appendChild(script);
    }

      这样把请求的url,传入loadJS函数,得到一样的结果。

    复制代码 代码如下:

    loadJS('http://www.b.com/b.php?callback=add');

      因为是动态创建script,请求成功返回,JS代码就立即执行,如果请求失败是没有任何提示的。因此自定义的参数选项: _opts.success 能调用,_opts.error不能调用。

      ajax处理jsonp也有两种情况:

      1. 设置了请求URL后的参数 callback=add 特别是定义了函数名add,请求成功返回,JS代码就立即执行(这里就是调用 add({"a":8,"b":2})  )

      2. 在_opts.success中处理JSON数据,就是请求成功返回,JS代码不执行,并把函数中的参数挪出来,作为_opts.success的参数返回( 这里相当于处理字符串 'add({"a":8,"b":2})' ,去掉 'add(' 和 ‘)',得到 {"a":8,"b":2} )

      处理dataType为html

       如果不处理HTML片段中script标签,直接把responseText返回值插入DOM树就可以了。如果要处理script,就要把HTML片段中的script标签找出来,对买个script单独处理,并注意是script标签中包含的JS代码还是通过src请求的。

      处理dataType为script

      如果要跨域时,用创建script的方式,和处理jsonp类似; 不跨域,使用 responseText 属性获取返回的数据,可以用 eval 来让代码执行,也可以创建script来执行。

    function addJS(text) {
      var doc = document, script = doc.createElement('script'), head = doc.getElementsByTagName('body')[0];
      script.type = 'text/javascript';
      script.text = text;
      body.appendChild(script);
    }
    

      到此ajax差不多分析完了,根据实际需要,添加各种功能,去思考每种功能是怎样实现的,并能找到解决方法。

    以上内容就是小编跟大家分享的不用库(框架)自己写ajax,希望大家喜欢。

    您可能感兴趣的文章:
    • Ajax 框架学习笔记
    • 无框架 Ajax分页(原创)
    • AJAX 图片展示框架56个 提升开发效率
    • AJAX 验证框架13个
    • PHP 开源AJAX框架14种
    • jquery 框架使用教程 AJAX篇
    • Jquery AJAX 框架的使用方法
    • 基于JQuery框架的AJAX实例代码
    • javascript之AJAX框架使用说明
    • asp.net省市三级联动的DropDownList+Ajax的三种框架(aspnet/Jquery/ExtJs)示例
    • 简单的前端js+ajax 购物车框架(入门篇)
    上一篇:如何解决Ajax访问不断变化的session的值不一致以及HTTP协议中的GET、POST的区别
    下一篇:JQuery中$.ajax()方法参数详解
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    简单介绍不用库(框架)自己写ajax 简单,介绍,不用,库,框架,