>  기사  >  웹 프론트엔드  >  라이브러리(프레임워크)를 사용하지 않고 직접 Ajax를 작성하는 방법에 대한 간략한 소개

라이브러리(프레임워크)를 사용하지 않고 직접 Ajax를 작성하는 방법에 대한 간략한 소개

亚连
亚连원래의
2018-05-24 16:32:221519검색

이 글에서는 라이브러리(프레임워크) 없이 ajax를 작성하는 방법을 소개합니다. 관심 있는 친구들은 함께 배울 수 있습니다.

보통 ajax는 데이터를 요청하고 라이브러리(프레임워크)를 로드하는 데 사용됩니다.

 Ajax를 작성하면 문제 해결 과정을 경험하고 기술적 역량을 향상할 수 있습니다. 둘째, 때로는 직장에서 그렇게 큰 라이브러리(프레임워크)가 필요하지 않을 때도 있으므로 직접 작성해 보는 것은 어떨까요?

먼저 인기 있는 jQuery가 ajax를 호출하는 방법을 살펴보겠습니다

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

이런 호출이 매우 편안하고 편리한가요? 직접 작성하실 때 이 디자인 방법을 참고하셔도 좋습니다. 너무 복잡할 필요도 없고 딱 필요한 것만 만족스럽습니다.

 먼저 ajax의 기본 지식을 이해하세요

 XMLHttpRequest 객체

 , Opera)는 모두 XMLHttpRequest 객체를 지원합니다(IE5 및 IE6은 ActiveXObject를 사용합니다).

  호환 가능한 XMLHttpRequest 개체 만들기

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

//메소드: 요청 유형;

//url: 요청된 URL //async: true(비동기) 또는 false(동기)xhr.send(string);

// // 서버에 요청 보내기

//string: POST 요청에만 사용됨
//GET은 POST 요청 방식보다 간단하고 빠르며 대부분의 경우에 사용할 수 있습니다
//다음과 같은 상황에서는 POST 요청을 사용하세요 :
//캐시된 파일을 사용할 수 없습니다(서버의 파일 또는 데이터베이스 업데이트)
//서버에 대용량 데이터 전송(POST에는 데이터 제한 없음)
//알 수 없는 문자가 포함된 사용자 입력을 보낼 때 POST가 GET보다 안정적입니다. XMLHttpRequest 객체의 responseXML 속성을 사용하여 서버로부터 응답을 얻습니다.

  서버의 응답이 XML이고 XML 객체로 구문 분석해야 하는 경우 responseXML 속성을 사용하세요.

  서버의 응답이 XML이 아닌 경우 문자열 형식으로 응답을 반환하는 responseText 속성을 사용하세요.

 
 onreadystatechange event

 요청이 서버로 전송되면 몇 가지 응답 기반 작업을 수행해야 합니다. ReadyState가 변경될 때마다 onreadystatechange 이벤트가 트리거됩니다. ReadyState 속성은 XMLHttpRequest의 상태 정보를 저장합니다.

 

XMLHttpRequest 객체의 세 가지 중요한 속성:

  

onreadystatechange

  //Storage 함수(또는 함수 이름), 이 함수는 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(&#39;?&#39;) < 0 ? &#39;?&#39; : &#39;&&#39;) + &#39;_=&#39;+ (+new Date());
xhr.setRequestHeader(&#39;Content-type&#39;, &#39;application/x-www-form-urlencoded&#39;);


나만의 Ajax 작성 시작하기

먼저 기본을 작성하고 참조용으로 다양한 매개변수 옵션을 정의합니다.

var $ = (function(){
  //辅助函数 序列化参数 
  function param(data){
    //..  
  }
 
  function ajax(opts){
    var _opts = {
      url    : &#39;/&#39;,       //发送请求URL地址
      type    : &#39;GET&#39;,      //发送请求的方式 GET(默认), POST
      dataType  : &#39;&#39;,        //预期服务器返回的数据类型 xml, html, text, json, jsonp, script
      data    : null,       //发送的数据 &#39;key=value&key=value&#39;, {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(&#39;Microsoft.XMLHTTP&#39;);
    for(key in opts) _opts[key] = opts[key];        
     
    /*
    if(_opts.dataType.toLowerCase() === &#39;script&#39;){
      //..
    }
    if(_opts.dataType.toLowerCase() === &#39;jsonp&#39;){
      //..
    }
    */
    if(_opts.type.toUpperCase() === &#39;GET&#39;){
      if(param(_opts.data) !== &#39;&#39;){
        _opts.url += (_opts.url.indexOf(&#39;?&#39;) < 0 ? &#39;?&#39; : &#39;&&#39;) + param(_opts.data);
      }
      !_opts.cache && ( _opts.url += (_opts.url.indexOf(&#39;?&#39;) < 0 ? &#39;?&#39; : &#39;&&#39;) + &#39;_=&#39;+(+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 &#39;xml&#39;:
              xhrdata = xhr.responseXML;
            break;
            case &#39;json&#39;:
              xhrdata = window.JSON && window.JSON.parse ? JSON.parse(xhr.responseText) : eval(&#39;(&#39; + xhr.responseText + &#39;)&#39;);
            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() === &#39;POST&#39;){
      xhr.setRequestHeader(&#39;Content-type&#39;, &#39;application/x-www-form-urlencoded&#39;);
    }
    xhr.send(_opts.type.toUpperCase() === &#39;GET&#39; ? 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(&#39;script&#39;), body = doc.getElementsByTagName(&#39;body&#39;)[0];
  script.type = &#39;text/javascript&#39;;
  if (script.readyState) { 
    script.onreadystatechange = function() {
      if (script.readyState == &#39;loaded&#39; || script.readyState == &#39;complete&#39;) {
        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(&#39;script&#39;), head = doc.getElementsByTagName(&#39;body&#39;)[0];
  script.type = &#39;text/javascript&#39;;
  script.text = text;
  body.appendChild(script);
}

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

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

MVC中基于Ajax和HTML5实现文件上传功能

jquery与php结合实现AJAX长轮询

初步了解JavaScript,Ajax,jQuery,并比较三者关系

위 내용은 라이브러리(프레임워크)를 사용하지 않고 직접 Ajax를 작성하는 방법에 대한 간략한 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.