ホームページ  >  記事  >  ウェブフロントエンド  >  ライブラリ(フレームワーク)を使わずに自分で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 ActiveXObject('Microsoft.XMLHTTP');

//メソッド: GET または POST;

//url: リクエストされた URL

//async: true (非同期) または false (同期)

xhr.send(string); // // リクエストをサーバーに送信します //string: POST リクエストにのみ使用されます

//GET は POST リクエストメソッドよりも簡単かつ高速で、ほとんどの場合に使用できます

//以下の状況では、POST リクエストを使用してください:
//キャッシュされたファイルは使用できません (サーバー上のファイルまたはデータベースを更新する)
//大量のデータをサーバーに送信します(POSTにはデータ制限がありません)
//不明な文字を含むユーザー入力を送信する場合、GETよりPOSTの方が安定しています 信頼性が高いです



サーバー応答


responseTextまたはXMLHttpRequest オブジェクトの responseXML 属性を使用して、サーバーからの応答を取得します。

サーバーからの応答が XML であり、XML オブジェクトとして解析する必要がある場合は、responseXML 属性を使用します。

サーバーからの応答が XML でない場合は、responseText 属性を使用して、応答を文字列として返します。

onreadystatechangeイベント

リクエストがサーバーに送信されると、いくつかの応答ベースのタスクを実行する必要があります。 readyState が変化するたびに、onreadystatechange イベントがトリガーされます。 readyState 属性には、XMLHttpRequest のステータス情報が格納されます。

XMLHttpRequest オブジェクトの 3 つの重要な属性:

onreadystatechange

//ストレージ関数 (または関数名)、readyState 属性が変更されるたびにこの関数が呼び出されます

readyState /私たちのXMLHttpRequest が保存され、0 から 4 に変化します0: リクエストは初期化されていません

1: サーバー接続が確立されました

2: リクエストが受信されました3: リクエストは処理中です4: リクエストは完了しましたそして応答は準備完了です


status

//200: "OK", 404: Page not found

onreadystatechange イベントでは、サーバー応答の処理準備ができたときに実行するタスクを指定します。 readyState が 4 の場合、ステータスが 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 を書き始めます


まず基本的な 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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。