前の言葉
1999 年、Microsoft は IE5 をリリースし、JavaScript スクリプトがサーバーへの HTTP リクエストを開始できるようにするという新機能を初めて導入しました。この機能は当時は注目を集めませんでしたが、2004 年に Gmail がリリースされ、2005 年に Google マップがリリースされてから広く注目を集めました。 2005 年 2 月に、ajax という用語が初めて正式に提案され、この機能に関する一連の開発手法を指しました。それ以来、ajax はスクリプトで開始される HTTP 通信の代名詞となり、W3C も 2006 年に国際標準をリリースしました。この記事は、ajax シリーズの最初の記事です - XHR オブジェクトの概要
Ajax は、asynchronous javascript and XML の略語で、中国語訳は非同期 javascript と XML です。ページはより良いユーザーエクスペリエンスをもたらします。名前には XML が含まれていますが、Ajax 通信はデータ形式とは関係ありません
Ajax には次の手順が含まれます: 1. AJAX オブジェクトを作成します。 2. HTTP リクエストを発行します。 3. サーバーから返されたデータを受信します。ページデータ
概要 一言で言えば、ajaxはネイティブXMLHttpRequest
オブジェクトを通じてHTTPリクエストを送信し、サーバーから返されたデータを取得した後、それを処理します
ajaxテクノロジーの中核はXMLHttpRequestオブジェクト(略して XHR)、Microsoft によって最初に開発された機能が導入され、後に他のブラウザー プロバイダーでも同様の実装が提供されました。 XHR は、サーバーにリクエストを送信し、サーバーの応答を解析するためのスムーズなインターフェイスを提供します。サーバーからより多くの情報を非同期的に取得できます。つまり、ユーザーがクリックした後、ページを更新せずに新しいデータを取得できます
IE5 が最初です。 XHR オブジェクトを導入するブラウザ。 IE5 では、XHR オブジェクトは MSXML ライブラリの ActiveX オブジェクトを通じて実装されますが、IE7+ およびその他の標準ブラウザーはネイティブ XHR オブジェクトをサポートしています
XMLHTTPRequest() はコンストラクターであるため、XHR オブジェクトの作成は XHR オブジェクトのインスタンス化とも呼ばれます。以下は互換性のある XHR オブジェクトの書き方です
var xhr; if(window.XMLHttpRequest){ xhr = new XMLHttpRequest(); }else{ xhr = new ActiveXObject('Microsoft.XMLHTTP'); }
[注意] N 個の異なるリクエストを作成したい場合は、N 個の異なる XHR オブジェクトを使用する必要があります。もちろん、既存の XHR オブジェクトを再利用することは可能ですが、これにより、そのオブジェクトを通じて以前に保留されていたリクエストが終了します
open()
XHR オブジェクトを使用するときに呼び出される最初のメソッド以下に示すように、open() です。このメソッドは 3 つのパラメータを受け入れます
xhr.open("get","example.php", false);
1. open() メソッドの最初のパラメータは、リクエストの送信方法を指定するために使用されます。ただし、通常は大文字を使用します。 「GET」と「POST」は広くサポートされています
「GET」は通常のリクエストに使用され、URL がリクエストされたリソースを完全に指定する場合、リクエストがサーバーに副作用を及ぼさない場合、およびサーバーの応答が次の場合に適しています。キャッシュ可能
HTMLフォームでは「POST」メソッドがよく使われます。リクエスト本文には追加データが含まれており、このデータは多くの場合サーバー上のデータベースに保存されます。同じ URL に対して POST リクエストを繰り返すと、サーバーから異なる応答が返される可能性があるため、このメソッドを使用したリクエストはキャッシュしないでください
「GET」と「POST」に加えて、パラメータには「HEAD」、「OPTIONS」、 "置く" "。セキュリティ上のリスクがあるため、「CONNECT」、「TRACE」、「TRACK」の使用は禁止されています
【注意】HTTP プロトコルの一般的に使用される 8 つのメソッドの詳細な紹介は、ここに移動します
2. の後半open() メソッド 最初のパラメータは、コードが実行される現在のページに相対的な URL で、リクエストは同じポートとプロトコルを使用して同じドメイン内の URL にのみ送信できます。 URL とリクエストを開始するページに差異がある場合、セキュリティ エラーが発生します
3. open() メソッドの 3 番目のパラメータは、リクエストを非同期に送信するかどうかを示すブール値です。入力されていない場合は、 , デフォルトは true で、リクエストが非同期に送信されることを示します
4. パスワードで保護された URL をリクエストする場合は、認証に使用するユーザー名とパスワードを 4 番目と 5 番目のパラメータとして open() メソッドに渡します
send( )
send() メソッドは、リクエストの本文として送信されるデータである 1 つのパラメータを受け取ります。 send() メソッドを呼び出した後、リクエストはサーバーにディスパッチされます
GET メソッドの場合、send() メソッドにはパラメーターがありません。POST メソッドの場合、パラメーターは null です。 send() メソッドは送信するデータです
xhr.open("get", "example.txt", false); xhr.send(null);
完全な HTTP レスポンスは、ステータス コード、レスポンス ヘッダー コレクション、レスポンス本文で構成されます。レスポンスを受け取った後は、XHRオブジェクトのプロパティやメソッドを通じて利用することができます。プロパティは主に以下の4つです
responseText: 作为响应主体被返回的文本(文本形式) responseXML: 如果响应的内容类型是'text/xml'或'application/xml',这个属性中将保存着响应数据的XML DOM文档(document形式) status: HTTP状态码(数字形式) statusText: HTTP状态说明(文本形式)
在接收到响应后,第一步是检查status属性,以确定响应已经成功返回。一般来说,可以将HTTP状态码为200作为成功的标志。此时,responseText属性的内容已经就绪,而且在内容类型正确的情况下,responseXML也可以访问了。此外,状态码为304表示请求的资源并没有被修改,可以直接使用浏览器中缓存的版本;当然,也意味着响应是有效的
无论内容类型是什么,响应主体的内容都会保存到responseText属性中,而对于非XML数据而言,responseXML属性的值将为null
if((xhr.status >=200 && xhr.status
如果接受的是同步响应,则需要将open()方法的第三个参数设置为false,那么send()方法将阻塞直到请求完成。一旦send()返回,仅需要检查XHR对象的status和responseText属性即可
同步请求是吸引人的,但应该避免使用它们。客户端javascript是单线程的,当send()方法阻塞时,它通常会导致整个浏览器UI冻结。如果连接的服务器响应慢,那么用户的浏览器将冻结
<button>获取信息</button> <div></div> <script> btn.onclick = function(){ //创建xhr对象 var xhr; if(window.XMLHttpRequest){ xhr = new XMLHttpRequest(); }else{ xhr = new ActiveXObject('Microsoft.XMLHTTP'); } //发送请求 xhr.open('get','/uploads/rs/26/ddzmgynp/message.xml',false); xhr.send(); //同步接受响应 if(xhr.readyState == 4){ if(xhr.status == 200){ //实际操作 result.innerHTML += xhr.responseText; } } } </script>
//message.xml <p>hello world</p>
如果需要接收的是异步响应,这就需要检测XHR对象的readyState属性,该属性表示请求/响应过程的当前活动阶段。这个属性可取的值如下:
0(UNSENT):未初始化。尚未调用open()方法 1(OPENED):启动。已经调用open()方法,但尚未调用send()方法 2(HEADERS_RECEIVED):发送。己经调用send()方法,且接收到头信息 3(LOADING):接收。已经接收到部分响应主体信息 4(DONE):完成。已经接收到全部响应数据,而且已经可以在客户端使用了
理论上,只要readyState属性值由一个值变成另一个值,都会触发一次readystatechange事件。可以利用这个事件来检测每次状态变化后readyState的值。通常,我们对readyState值为4的阶段感兴趣,因为这时所有数据都已就绪
[注意]必须在调用open()之前指定onreadystatechange 事件处理程序才能确保跨浏览器兼容性,否则将无法接收readyState属性为0和1的情况
xhr.onreadystatechange = function(){ if(xhr.readyState === 4){ if(xhr.status == 200){ alert(xhr.responseText); } } }
<button>获取信息</button> <div></div> <script> btn.onclick = function(){ //创建xhr对象 var xhr; if(window.XMLHttpRequest){ xhr = new XMLHttpRequest(); }else{ xhr = new ActiveXObject('Microsoft.XMLHTTP'); } //异步接受响应 xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ if(xhr.status == 200){ //实际操作 result.innerHTML += xhr.responseText; } } } //发送请求 xhr.open('get','message.xml',true); xhr.send(); } </script>
//message.xml <p>hello world</p>
XHR对象的timeout属性等于一个整数,表示多少毫秒后,如果请求仍然没有得到结果,就会自动终止。该属性默认等于0,表示没有时间限制
如果请求超时,将触发ontimeout事件
[注意]IE8-浏览器不支持该属性
xhr.open('post','test.php',true); xhr.ontimeout = function(){ console.log('The request timed out.'); } xhr.timeout = 1000; xhr.send();
使用AJAX接收数据时,由于网络和数据大小的原因,并不是立刻就可以在页面中显示出来。所以,更好的做法是,在接受数据的过程中,显示一个类似loading的小图片,并且禁用按钮;当数据完全接收后,再隐藏该图片,并启用按钮
<button>获取信息</button> <img alt="ajaxシリーズのXHRオブジェクトの理解" > <div></div> <script> var add = (function(){ var counter = 0; return function(){ return ++counter; } })(); btn.onclick = function(){ img.style.display = 'inline-block'; btn.setAttribute('disabled',''); //创建xhr对象 var xhr; if(window.XMLHttpRequest){ xhr = new XMLHttpRequest(); }else{ xhr = new ActiveXObject('Microsoft.XMLHTTP'); } //异步接受响应 xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ if(xhr.status == 200){ img.style.display = 'none'; btn.removeAttribute('disabled'); var data = JSON.parse(xhr.responseText); var sum = add() - 1; if(sum < data.length){ result.innerHTML += data[sum]; } } } } //发送请求 xhr.open('get','data.php',true); xhr.send(); } </script>
<?php echo json_encode([1,2,3,4,5]); ?>
最後に
サンプルのデモを通じて、ajax フロントエンド自体の内容は難しくないことがわかりました。ただし、ajax はバックエンドとネットワークの知識が必要なため、習得するのは簡単ではありません。今後のブログ投稿では、ajax の主要な内容を徐々に詳しく紹介していきます
以上がajaxシリーズのXHRオブジェクトの理解の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。