کار با پاسخ های AJAX

13 اردیبهشت 1398
Advanced-Javascript-ajax-http-responses

پاسخ سرور به AJAX

قبلا گفته بودیم که readyState وضعیت XMLHttpRequest را در خود نگه می دارد و از طرفی onreadystatechange حامل تابعی است که در صورت تغییر readyState (تغییر وضعیت درخواست) اجرا می شود. همچنین خصوصیات status و statusText نیز وضعیت شیء XMLHttpRequest را در خود نگه میدارند.

خصوصیت توضیح
onreadystatechange تابعی را تعریف می کند که پس از تغییر خاصیت readyState اجرا شود
readyState وضعیت XMLHttpRequest را نشان داده که می تواند یکی از مقادیر زیر باشد:

0: درخواستی ارسال نشده است

1: اتصال به سرور برقرار شده است

2: درخواست توسط سرور دریافت شده است

3: درخواست در حال پردازش است

4: درخواست انجام شده و پاسخ آماده است

status وضعیت درخواست را نشان داده که می تواند یکی از مقادیر زیر باشد:

200: به معنی "OK" است

403: به معنی "Forbidden" (غیر مجاز) است

404: به معنی "Not Found" (پیدا نشد) است

statusText به جای ارائه ی وضعیت درخواست به صورت عددی، آن را به صورت رشته ای (مثل "OK" یا "Not Found") برمیگرداند

بنابراین تابع onreadystatechange هر زمان که وضعیت درخواست تغییر کند صدا زده می شود؛ زمانی که readyState برابر 4 و وضعیت (status) برابر با 200 باشد، درخواست ما پاسخ داده شده و آماده است:

<!DOCTYPE html>
<html>
<body>

<div id="demo">
<h2>The XMLHttpRequest Object</h2>
<button type="button" onclick="loadDoc()">Change Content</button>
</div>

<script>
function loadDoc() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("demo").innerHTML =
      this.responseText;
    }
  };
  xhttp.open("GET", "ajax_info.txt", true);
  xhttp.send();
}
</script>

</body>
</html>

شما می توانید از این کد یا کدی شبیه به آن برای گرفتن درخواست استفاده کنید. ما در این کد status و readyState را چک میکنیم و سپس پاسخ را دریافت می کنیم.

نکته: در طی یک درخواست سالم AJAX، مقدار onreadystatechange چهار بار تغییر می کند (1 تا 4 برای حالت های readyState).

استفاده از callback function

توابع callback توابعی هستند که به جای یک پارامتر وارد یک تابع دیگر می شوند. اگر شما بیشتر از یک درخواست AJAX را در سایت خود دارید باید یک تابع برای اجرای شیء XMLHttpRequest و یک تابع callback برای هر درخواست AJAX ساخته باشید.

این تابع باید شامل URL باشد و بگوید در صورت دریافت پاسخ چه تابعی اجرا شود:

<!DOCTYPE html>
<html>
<body>

<div id="demo">

<h2>The XMLHttpRequest Object</h2>

<button type="button" onclick="loadDoc('ajax_info.txt', myFunction)">Change Content
</button>
</div>

<script>
function loadDoc(url, cFunction) {
  var xhttp;
  xhttp=new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      cFunction(this);
    }
  };
  xhttp.open("GET", url, true);
  xhttp.send();
}
function myFunction(xhttp) {
  document.getElementById("demo").innerHTML =
  xhttp.responseText;
}
</script>
</body>
</html>

در این مثال با کلیک روی دکمه ای فرضی تابعی به نام loadDoc اجرا می شود که یکی از پارامتر هایش تابع دیگری به نام myFunction است. به myFunction یک تابع callback می گوییم.

خصوصیات پاسخ سرور:

خصوصیت توضیحات
responseText پاسخ را به صورت رشته ای دریافت می کند.
responseXML پاسخ را به صورت XML دریافت می کند.

متد های پاسخ سرور:

متد توضیحات
getResponseHeader() اطلاعات خاصی از header را از سرور می گیرد.
getAllResponseHeaders() تمام اطلاعات header را از سرور می گیرد.

خصوصیت responseText

خصوصیت responseText پاسخ سرور را به صورت یک رشته ی جاوا اسکریپتی برمیگرداند و شما میتوانید به دلخواه خود از آن استفاده کنید:

<!DOCTYPE html>
<html>
<body>

<div id="demo">
<h2>The XMLHttpRequest Object</h2>
<button type="button" onclick="loadDoc()">Change Content</button>
</div>

<script>
function loadDoc() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("demo").innerHTML =
      this.responseText;
    }
  };
  xhttp.open("GET", "ajax_info.txt", true);
  xhttp.send();
}
</script>

</body>
</html>

در مثال بالا پاسخ سرور را به صورت رشته ای دریافت کرده ایم و سپس به HTML صفحه تزریق کرده ایم. منظور من این قسمت از کد است:

document.getElementById("demo").innerHTML = xhttp.responseText;

خصوصیت responseXML

شیء XMLHttpRequest یک XML parser (تجزیه کننده ی XML) داخلی دارد. از طرفی responseXML پاسخ سرور را به صورت یک شیء XML DOM برمیگرداند. بنابراین شما می توانید با استفاده از خصوصیت responseXML پاسخ را به صورت یک شیء XML DOM تجزیه کنید:

<!DOCTYPE html>
<html>
<body>

<h2>The XMLHttpRequest Object</h2>

<p id="demo"></p>
 
<script>
var xhttp, xmlDoc, txt, x, i;
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
  if (this.readyState == 4 && this.status == 200) {
    xmlDoc = this.responseXML;
    txt = "";
    x = xmlDoc.getElementsByTagName("ARTIST");
    for (i = 0; i < x.length; i++) {
      txt = txt + x[i].childNodes[0].nodeValue + "<br>";
    }
    document.getElementById("demo").innerHTML = txt;
  }
};
xhttp.open("GET", "cd_catalog.xml", true);
xhttp.send();
</script>

</body>
</html>

مشاهده ی خروجی

در این مثال ابتدا مانند مثال های قبلی پاسخ را از سرور دریافت کرده ایم اما تفاوت آنجاست که پاسخ را به صورت XML گرفته ایم. سپس با یک حلقه ی for تک تک node ها را جدا کرده و در آخر آن ها تگ <br> گذاشته ایم تا هر کدام در یک خط جداگانه قرار بگیرند. در آخر همان چیزی را که در خروجی می بینید ایجاد کرده ایم. همچنین ساختار فایل XML اصلی را میتوانید در این صفحه مشاهده کنید.

متد ()getAllResponseHeaders

متد ()getAllResponseHeaders تمام اطلاعات header را از پاسخ سرور گرفته و به ما برمیگرداند:

<!DOCTYPE html>
<html>
<body>

<h2>The XMLHttpRequest Object</h2>

<p>The getAllResponseHeaders() function returns all the header information of a resource, like length, server-type, content-type, last-modified, etc:</p>

<p id="demo"></p>

<script>
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
  if (this.readyState == 4 && this.status == 200) {
    document.getElementById("demo").innerHTML =
    this.getAllResponseHeaders();
  }
};
xhttp.open("GET", "ajax_info.txt", true);
xhttp.send();
</script>

</body>
</html>

مشاهده ی خروجی

همانطور که در خروجی می بینید تمام اطلاعات header به صورت پشت سر هم به ما برگردانده شده اند. در صورت نیاز می توانید با توابع مختلف و بر اساس کاری که می خواهید انجام دهید از آن ها استفاده کنید.

متد ()getResponseHeader

متد ()getResponseHeader بر خلاف متد ()getAllResponseHeaders فقط بعضی از اطلاعات header را برمیگرداند. کدام اطلاعات؟ آن اطلاعاتی که شما بخواهید و دستورش را بدهید:

<!DOCTYPE html>
<html>
<body>

<h2>The XMLHttpRequest Object</h2>

<p>The getResponseHeader() function is used to return specific header information from a resource, like length, server-type, content-type, last-modified, etc:</p>

<p>Last modified: <span id="demo"></span></p>

<script>
var xhttp=new XMLHttpRequest();
xhttp.onreadystatechange = function() {
  if (this.readyState == 4 && this.status == 200) {
    document.getElementById("demo").innerHTML =
    this.getResponseHeader("Last-Modified");
  }
};
xhttp.open("GET", "ajax_info.txt", true);
xhttp.send();
</script>

</body>
</html>

مشاهده ی خروجی

در این مثال تنها اطلاعات مربوط به Last-Modified از header را خواسته ایم بنابراین تنها همان مقدار به ما برگردانده شده است.

امیدوارم از این قسمت لذت برده باشید.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری جاوا اسکریپت پیشرفته توصیه می‌کند:
نویسنده شوید

دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.