AJAX

AJAX

一、AJAX简介

1、什么是AJAX?

1、AJAX是异步的JavaScript和XML(Asynchronous JavaScript And XML),是指一种创建交互式网页应用的网页开发技术。(XML已极少使用)

2、本质:

  • 简单点说,就是使用 XMLHttpRequest (核心)对象向服务器发异步请求,从服务器获得数据,然后用 javascript 来操作DOM更新页面的技术。
  • ajax 是一种浏览器通过 js 异步发起请求,局部更新页面的技术。
    • Ajax 请求的局部更新,浏览器地址栏不会发生变化。
    • 局部更新不会舍弃原来页面的内容。

3、使用AJAX更多的是编写客户端代码!

2、最大的优点:

AJAX最吸引人的就是它的“异步”特性,也就是说它可以在不重新刷新页面的情况下与服务器通信,交换数据,或更新页面。

因此可以实现:

  • 在不重新加载页面的情况下发送请求给服务器(最重要的部分)。
  • 接受并使用从服务器发来的数据。

二、原生AJAX请求的案例

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
    <script type="text/javascript">
    // 在这里使用 javaScript 语言发起 Ajax 请求,访问服务器 AjaxServlet 中 javaScriptAjax方法
    function ajaxRequest() {
    // 1 、我们首先要创建 XMLHttpRequest
    var xmlhttprequest = new XMLHttpRequest();
    // 2 、调用 open 方法设置请求参数
    xmlhttprequest.open("GET","http://localhost:8080/16_json_ajax_i18n/ajaxServlet?action=javaScriptAj
    ax",true)
    // 3 、在 send 方法前绑定 onreadystatechange 事件,处理请求完成后的操作。
    xmlhttprequest.onreadystatechange = function(){
    if (xmlhttprequest.readyState == 4 && xmlhttprequest.status == 200) {
    var jsonObj = JSON.parse(xmlhttprequest.responseText);
    // 把响应的数据显示在页面上
    document.getElementById("div01").innerHTML = " 编号:" + jsonObj.id + " , 姓名:" +
    jsonObj.name;
    }
    }
    // 4 、调用 send 方法发送请求
    xmlhttprequest.send();
    }
    </script>
</head>
<body>
    <button onclick="ajaxRequest()">ajax request</button>
    <div id="div01">
    </div>
</body>
</html>

原生js实现ajax方法:

var Ajax = {
    get: function(url,callback){
        // XMLHttpRequest对象用于在后台与服务器交换数据
        var xhr=new XMLHttpRequest();
        xhr.open('GET',url,false);
        xhr.onreadystatechange=function(){
            // readyState == 4说明请求已完成
            if(xhr.readyState==4){
                if(xhr.status==200 || xhr.status==304){
                    console.log(xhr.responseText);
                    callback(xhr.responseText);
                }
            }
        }
        xhr.send();
    },

    // data应为'a=a1&b=b1'这种字符串格式,在jq里如果data为对象会自动将对象转成这种字符串格式
    post: function(url,data,callback){
        var xhr=new XMLHttpRequest();
        xhr.open('POST',url,false);
        // 添加http头,发送信息至服务器时内容编码类型
        xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
        xhr.onreadystatechange=function(){
            if (xhr.readyState==4){
                if (xhr.status==200 || xhr.status==304){
                    // console.log(xhr.responseText);
                    callback(xhr.responseText);
                }
            }
        }
        xhr.send(data);
    }
}

三、JQuery提供的Ajax

1、$.ajax 方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KfaCVD6I-1609734239441)(AJAX%E5%9F%BA%E7%A1%80.assets/image-20210104112746918.png)]

$("#ajaxBtn").click(function(){
    $.ajax({       			      url:"http://localhost:8080/16_json_ajax_i18n/ajaxServlet",
        // data:"action=jQueryAjax",
        data:{action:"jQueryAjax"},
        type:"GET",
        success:function (data) {
            // alert(" 服务器返回的数据是: " + data);
            // var jsonObj = JSON.parse(data);
            $("#msg").html(" 编号:" + data.id + " , 姓名:" + data.name);
        },
        dataType : "json"
    });
});
2、 . g e t 方 法 和 .get 方法和 .get.post 方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bo1DkmN5-1609734239446)(AJAX%E5%9F%BA%E7%A1%80.assets/image-20210104112918055.png)]

// ajax--get 请求
$("#getBtn").click(function(){
  $.get("http://localhost:8080/16_json_ajax_i18n/ajaxServlet","action=jQueryGet",function (data) {
    $("#msg").html(" get 编号:" + data.id + " , 姓名:" + data.name);
    },"json");
    });
    // ajax--post 请求
    $("#postBtn").click(function(){
    $.post("http://localhost:8080/16_json_ajax_i18n/ajaxServlet","action=jQueryPost",function (data)
    {
        $("#msg").html(" post 编号:" + data.id + " , 姓名:" + data.name);
    },"json");
});
3、$.getJSON 方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gM9RHdy1-1609734239448)(AJAX%E5%9F%BA%E7%A1%80.assets/image-20210104113050559.png)]

// ajax--getJson 请求
$("#getJSONBtn").click(function(){   		    $.getJSON("http://localhost:8080/16_json_ajax_i18n/ajaxServlet","action=jQueryGetJSON",function
    (data) {
    	$("#msg").html(" getJSON 编号:" + data.id + " , 姓名:" + data.name);
    });
});
4、表单序列化 serialize()

serialize()可以把表单中所有表单项的内容都获取到,并以name=value&name=value 的形式进行拼接。

// ajax 请求
$("#submit").click(function(){
    // 把参数序列化
 $.getJSON("http://localhost:8080/16_json_ajax_i18n/ajaxServlet","action=jQuerySerialize&" +
    $("#form01").serialize(),function (data) {
    	$("#msg").html(" Serialize 编号:" + data.id + " , 姓名:" + data.name);
    });
});

四、 5 steps

Step 1 – 怎样发送http请求

为了使用JavaScript向服务器发送一个http请求,你需要一个包含必要函数功能的对象实例。这就是为什么会有 XMLHttpRequest 的原因。 这是IE浏览器的ActiveX对象 XMLHTTP的前身。 随后Mozilla,Safari和其他浏览器也都实现了类似的方法,被称为 XMLHttpRequest 。同时,微软也实现了XMLHttpRequest方法。

// Old compatibility code, no longer needed.
if (window.XMLHttpRequest) { // Mozilla, Safari, IE7+ ...
    httpRequest = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE 6 and older
    httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}

Note: 上面代码只是简单版的如何创建一个XMLHttp实例。更实际的例子,请看本篇文章的step 3。

发送一个请求后,你会收到响应。在这一阶段,你要告诉XMLHttp请求对象是由哪一个JavaScript函数处理响应,在设置了对象的 onreadystatechange属性后给他命名,当请求状态改变时调用函数。

httpRequest.onreadystatechange = nameOfTheFunction;

要注意的是,函数名后没有参数,因为你把一个引用赋值给了函数,而不是真正的调用了它。 此外,如果不使用函数名的方式,你还可以用JavaScript的匿名函数响应处理的动作,就像下面这样:

httpRequest.onreadystatechange = function(){
    // Process the server response here.
};

接下来,声明当你接到响应后要做什么,你要发送一个实际的请求,通过调用HTTP请求对象的 open()send() 方法,像下面这样:

httpRequest.open('GET', 'http://www.example.org/some.file', true);
httpRequest.send();
  • open() 的第一个参数是HTTP请求方法 - 有GET,POST,HEAD以及服务器支持的其他方法。 保证这些方法一定要是大写字母,否则其他一些浏览器(比如FireFox)可能无法处理这个请求。更多关于HTTP的请求方法,可以查看 W3C specs
  • 第二个参数是你要发送的URL。由于安全原因,默认不能调用第三方URL域名。 确保你在页面中使用的是正确的域名,否则在调用 open() 方法是会有 “permission denied” 错误提示。一个容易犯的错误是你企图通过 domain.tld 访问网站, 而不是使用 www.domain.tld。如果你真的需要向另一个域名发送请求, 可以查看 HTTP access control
  • 第三个参数是可选的,用于设置请求是否是异步的。如果设为 true (默认值),即开启异步,JavaScript就不会在此语句阻塞,使得用户能在服务器还没有响应的情况下与页面进行交互。

send() 方法的参数可以是任何你想发送给服务器的内容,如果是 POST 请求的话。发送表单数据时应该用服务器可以解析的格式,像查询语句:

"name=value&anothername="+encodeURIComponent(myVar)+"&so=on"

或者其他格式, 类似 multipart/form-data,JSON,XML等。

如果你使用 POST 数据,那就需要设置请求的MIME类型。比如,在调用 send() 方法获取表单数据前要有下面这个:

httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

Step 2 – 处理服务器响应

在发送请求时,你提供的JavaScript函数名负责处理响应:

httpRequest.onreadystatechange = nameOfTheFunction;

这个函数应该做什么?首先,函数要检查请求的状态。如果状态的值是 XMLHttpRequest.DONE (对应的值是4),意味着服务器响应收到了并且是没问题的,然后就可以继续执行。

if (httpRequest.readyState === XMLHttpRequest.DONE) {
    // Everything is good, the response was received.
} else {
    // Not ready yet.
}

全部readyState状态值都在 XMLHTTPRequest.readyState,如下也是:

  • 0 (未初始化) or (请求还未初始化)
  • 1 (正在加载) or (已建立****服务器链接)
  • 2 (加载成功) or (请求已接受)
  • 3 (交互) or (正在处理请求)
  • 4 (完成) or (请求已完成并且响应已准备好)

(Source)

接下来,点击HTTP响应的 response code。 可能的响应码都已经列在 W3C这个列表里。在下面的例子中,我们通过检查响应码 200 OK 判断AJAX有没有成功。

if (httpRequest.status === 200) {
    // Perfect!
} else {
    // There was a problem with the request.
    // For example, the response may have a 404 (Not Found)
    // or 500 (Internal Server Error) response code.
}

在检查完请求状态和HTTP响应码后, 你就可以用服务器返回的数据做任何你想做的了。你有两个方法去访问这些数据:

  • httpRequest.responseText – 服务器以文本字符的形式返回
  • httpRequest.responseXML – 以 XMLDocument 对象方式返回,之后就可以使用JavaScript来处理

注意上面这一步只在你发起异步请求时有效(即 open() 的第三个参数未特别指定或设为 true)。如果你你发起的是同步请求则不必使用函数,但是非常不推荐这样子做,它的用户体验很糟糕。

Step 3 – 一个简单的例子

让我们把所有的知识都集中起来做一个简单的HTTP请求。这个JavaScript会请求一个HTML文档 test.html,包含 “I’m a test” 内容。然后我们 alert() 响应的内容。注意这个例子我们只是用了JavaScript,没有用jQuery。而且,HTML,XML和PHP文件都要放在用一个目录下。

<button id="ajaxButton" type="button">Make a request</button>

<script>
(function() {
  var httpRequest;
  document.getElementById("ajaxButton").addEventListener('click', makeRequest);

  function makeRequest() {
    httpRequest = new XMLHttpRequest();

    if (!httpRequest) {
      alert('Giving up :( Cannot create an XMLHTTP instance');
      return false;
    }
    httpRequest.onreadystatechange = alertContents;
    httpRequest.open('GET', 'test.html');
    httpRequest.send();
  }

  function alertContents() {
    if (httpRequest.readyState === XMLHttpRequest.DONE) {
      if (httpRequest.status === 200) {
        alert(httpRequest.responseText);
      } else {
        alert('There was a problem with the request.');
      }
    }
  }
})();
</script>

在这个例子中:

  • 用户点击 “Make a request” 按钮;
  • 事件处理调用 makeRequest() 函数;
  • 请求已通过然后(onreadystatechange)传给 alertContents() 执行。
  • alertContents() 检查返回的响应是否OK,然后 alert() test.html 文件内容。

Note: 如果你向一个代码片段发送请求,将返回XML,而不是静态XML文件,在IE浏览器上则必须要设置响应头才能正常工作。如果不设置响应头为 Content-Type:application/xml ,IE浏览器会在你访问XML元素时抛出 “Object Expected” 错误。

Note 2: 如果不设置响应头 Cache-Control: no-cache 浏览器将会把响应缓存下来而且再也无法重新提交请求。你也可以添加一个总是不同的 GET 参数,比如时间戳或者随机数 (详情见 bypassing the cache)

Note 3: 如果变量 httpRequest 在全局范围内使用,它会在 makeRequest() 函数中被相互覆盖,从而导致资源竞争。为了避免这个情况,请在包含 AJAX 函数的闭包中声明 httpRequest变量。

在通信错误的事件中(例如服务器宕机),在访问响应状态 onreadystatechange 方法中会抛出一个例外。为了缓和这种情况,则可以使用 try...catchif...then 语句包裹起来。

function alertContents() {
  try {
    if (httpRequest.readyState === XMLHttpRequest.DONE) {
      if (httpRequest.status === 200) {
        alert(httpRequest.responseText);
      } else {
        alert('There was a problem with the request.');
      }
    }
  }
  catch( e ) {
    alert('Caught Exception: ' + e.description);
  }
}

Step 4 – 处理 XML 响应

在上一个例子中,在收到HTTP请求的响应后我们会请求对象的 responseText 属性,包含 test.html 文件的内容。现在我们试试 responseXML属性。

首先,我们创建一个稍后将要请求的有效的 XML 文档。文档(test.html)包含以下内容:

<?xml version="1.0" ?>
<root>
    I'm a test.
</root>

在脚本里我们只需要把请求行改为:

...
οnclick="makeRequest('test.xml')">
...

然后在 alertContents() 里,我们把 alert(httpRequest.responseText) 改为:

var xmldoc = httpRequest.responseXML;
var root_node = xmldoc.getElementsByTagName('root').item(0);
alert(root_node.firstChild.data);

这部分代码采用 responseXML 提供的 XMLDocument 对象,并使用 DOM 方法访问 XML 文档中包含的一些数据。你可以在这里查看 test.xml 并且在这里更新测试代码。

Step 5 – 处理数据

最后,我们发送一个数据给服务器并收到响应。这次我们用 JavaScript 请求动态页面,test.php 并返回一个计算后的字符串 - “Hello, [user date]”,并用 alert() 出来。

首先要添加一个文本到 HTML 中以方便用户输入名字:

<label>Your name: 
  <input type="text" id="ajaxTextbox" />
</label>
<span id="ajaxButton" style="cursor: pointer; text-decoration: underline">
  Make a request
</span>

还要添加事件处理程序,从表单中获取用户数据连同服务器端的UTL一并发送给 makeRequest() 函数:

  document.getElementById("ajaxButton").onclick = function() { 
      var userName = document.getElementById("ajaxTextbox").value;
      makeRequest('test.php',userName); 
  };

我们还要修改 makeRequest() 让它接受用户数据并将其发给服务器。把请求方法从 GET 改为 POST,把数据作为参数让httpRequest.send() 调用。

  function makeRequest(url, userName) {

    ...

    httpRequest.onreadystatechange = alertContents;
    httpRequest.open('POST', url);
    httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    httpRequest.send('userName=' + encodeURIComponent(userName));
  }

如果这就是服务器返回的全部内容,alertContents() 函数可以使用 step 3 中的相同函数写。可是,服务器会返回计算后的内容和原内容。所以,如果用户输入 “Jane” 在输入框中,那服务器就会返回如下内容:

{"userData":"Jane","computedString":"Hi, Jane!"}

为了在 alertContents() 中使用这个数据,我们可不能只是alert responseText ,我们要解析它并 alert conputedString,我们想要的属性:

function alertContents() {
  if (httpRequest.readyState === XMLHttpRequest.DONE) {
    if (httpRequest.status === 200) {
      var response = JSON.parse(httpRequest.responseText);
      alert(response.computedString);
    } else {
      alert('There was a problem with the request.');
    }
  }
}
test.php 文件应该包含以下内容:
$name = (isset($_POST['userName'])) ? $_POST['userName'] : 'no name';
$computedString = "Hi, " . $name;
$array = ['userName' => $name, 'computedString' => $computedString];
echo json_encode($array);

(httpRequest.status === 200) {
var response = JSON.parse(httpRequest.responseText);
alert(response.computedString);
} else {
alert(‘There was a problem with the request.’);
}
}
}
test.php 文件应该包含以下内容:
n a m e = ( i s s e t ( name = (isset( name=(isset(_POST[‘userName’])) ? $_POST[‘userName’] : ‘no name’;
$computedString = "Hi, " . $name;
$array = [‘userName’ => $name, ‘computedString’ => c o m p u t e d S t r i n g ] ; e c h o j s o n e n c o d e ( computedString]; echo json_encode( computedString];echojsonencode(array);




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值