{{ title }}
{{ errorMessage }}


{{ errorMessage }}





{{ registerSuccessMessage }}

Ajax全接触之原生js实现ajax请求

什么是ajax?

Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术,它能帮助我们与服务器进行数据交换,在无需重新加载页面的情况下实现异步更新页面内容。

Ajax没有出现之前,整个web世界都是同步的,每次与服务器进行交互的时候,页面需要重新加载才能更新数据。想象一下,当你在一个没有使用ajax的网站填写一个十余项的表单时,所有内容填写完毕并提交,这时服务器返回响应结果,页面重新加载提示你某一项填错了,然后又重新开始一项项填写......顿时心中有千万只草泥马在奔腾~

Ajax技术出现后,再也不用害怕填写表单了!每当我们填完某一项内容后,浏览器会将你的数据通过异步传递给服务器,后台校验数据后返回响应结果,浏览器接收返回的数据更新到页面中,这个过程是非常快且不需要重新加载页面的,所有内容填写完毕就可以愉快地点击提交了,再也不会出现提交之后再告诉我哪里填错了!

一个完整的Ajax请求由四部分组成:创建XHR对象 > 发送HTTP请求 > 接收服务器返回的数据 > 更新页面

什么是HTTP请求?

HTTP是一种无状态协议,它指的是不建立持久的链接,也就是说服务端不会保留连接的一些相关信息,一个客户端向服务器发出请求,然后web服务器返回响应,接着连接就被关闭,这个处理过程是没有记忆的,如果后续需要处理之前传递的信息,那就需要从新发送请。

一个完整的HTTP请求过程,通常有下面7个步骤:

  1. 1. 建立TCP连接
    2. web浏览器向web服务器发送请求命令
    3. web浏览器发送请求头信息
    4. web服务器应答
    5. web服务器发送应答头信息
    6. web服务器向浏览器发送数据
    7. web服务器关闭TCP连接

一个HTTP请求一般由四部分组成:

  1. 1.HTTP请求的方法或动作,比如是GET还是POST请求
    2.正在请求的URL
    3.请求头,包含一些客户端环境信息,身份验证信息等
    4.请求体,也就是请求正文,请求正文中可以包含客户提交的查询字符串信息,表单信息等等image.png

GET请求:一般用于信息获取,使用URL传递参数,对所发送信息的数量也有限制,一般在2000个字符

POST请求:一般用于修改服务器上的资源,对所发送信息的数量无限制

一个HTTP响应一般由三个部分组成:

  1. 1.一个数字和文字组成的状态码,用来显示请求是成功还是失败
    2.响应头,响应头也和请求头一样包含许多有用的信息,例如服务器类型、日期时间、内容类型和长度等
    3.响应体,也就是响应正文

image.pngimage.png

HTTP状态

HTTP状态码由3位数字构成,其中首位数字定义了状态码的类型:
1XX:信息类,表示收到web浏览器的请求,正在进一步的处理中
2XX:成功,表示用户请求被正确接收,理解和处理,例如:200 OK
3XX:重定向,表示请求没有成功,客户必须采取进一步的动作
4XX:客户端错误,表示客户端提交的请求有错误,例如404 NOT Found,意味着请求中所引用的文档不存在。
5XX:服务器错误,表示服务器不能完成对请求的处理:如500

XMLHttpRequest对象

原生js对象XMLHttpRequest提供了下面两个方法,可以帮助我们将请求发送到服务器:

open(method, url, async) // 调用ajax请求
send(string) // 将请求发送到服务器

open()和send()方法参数说明:
method:发送请求方法(GET/POST),不区分大小写
url:请求地址,可以是相对地址或绝对地址
async:同步(false)/异步(true),默认是异步请求,可以不填写async
string:传递请求体给服务器,注意:GET请求是没有请求体的,所以send方法的参数可以不填写,使用POST请求是需要填写send方法参数的。

其他方法和属性:

setRequestHeader():设置HTTP请求头信息,它告示浏览器你要发送的数据是什么格式

获取XMLHttpRequest响应:
responseText // 获得字符串形式的响应数据
responseXML // 获得XML形式的响应数据
status和statusText // 获取以数字和文本形式返回的HTTP状态码
getAllResponseHeader() // 获取所有的响应报头
getResponseHeader() // 查询响应中的某个字段的值(括号要传递查询的值)
readyState // 响应码
onreadystatechange = function(){} // 事件句柄 readyState 的值每次改变都会触发一次

参数说明:

setRequestHeader()方法一定要写在open()和send()方法中间,否则会报错;
设置请求头Content-Type:

发送json格式数据:
setRequestHeader("Content-type","application/json; charset=utf-8")

发送表单数据:
setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8")

发送html文本:
setRequestHeader("Content-type", "text/html; charset=utf-8")

编码可带可不带:
setRequestHeader("Content-type", "application/json")

值对大小写不敏感:
setRequestHeader("Content-type","Application/JSON; charset=utf-8")

readyState:这个属性是为了响应成功的时候得到通知,在实际操作中,需要监听这个属性的变化,这个属性的变化代表着服务器的响应变化,有以下响应码:

0:请求未初始化,open还没有调用
1:服务器连接已建立,open已经调用了
2:请求已接收,也就是接收到了头信息了
3:请求处理中,也就是接收到响应主体了
4:请求已完成,且响应已就绪,也就是响应完成了

使用onreadystatechange = function(){} 监听readyState属性的变化,这个事件在readyState属性每次变化后触发;在一些浏览器上,从0~1这个过程它不会被触发,不过我们只需要关心“4”这个过程就可以了。

实践例子 - 发送GET请求

看了这么多理论知识,双手是不是蠢蠢欲动了?让我们荡起双手撸代码吧!
通过员工查询案例实践,案例后台代码使用PHP搭建,结合Ajax技术实现查询员工信息的异步获取:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>异步获取员工数据</title>
</head>
<body>
  <h1>员工查询</h1>
  <label>请输入员工编号:</label>
  <input type="text" id="keyword" />
  <button id="search">查询</button>
  <p id="searchResult"></p>
  
  <script>
    document.getElementById("search").onclick = function(){
      // 实例化一个ajax对象
      var request = new XMLHttpRequest();
      // 查询员工信息需要知道员工的编码 需要传递给服务器
      request.open("GET","test.php?number=" + document.getElementById("keyword").value);
      request.send();
      // 监听服务器处理状态
      request.onreadystatechange = function(){
        if(request.readyState === 4){
          if(request.status === 200){
            // 将服务器返回的数据更新到页面中
            document.getElementById("searchResult").innerHTML = request.responseText;
          }else{
            alert("发生错误" + request.status)
          }
        }
      }
    }
  </script>
</body>
</html>

页面效果:

首先实例化一个XMLHttpRequest对象,然后调用XMLHttpRequest对象的open方法,用GET方式发送HTTP请求,test.php是请求的地址(test.php和当前文件在同一级目录),?后面是我们要传递给服务器的参数,获取input输入框值作为查询的参数传递给服务器。

然后调用send方法发送请求,使用onreadystatechange事件句柄监听readyState属性的变化,当readyState属性的值等于4时,说明请求已经完成且已接收到后端返回的数据;进一步判断status(HTTP状态码),若HTTP状态码为200时,代表HTTP请求成功,这时需要将服务器返回字符串形式的响应数据更新到页面中,否则弹出一个警告框,告诉用户请求发生错误。

提示:上面的例子中我们没有设置setRequestHeader()请求头,因为我们发送的数据html文本,这是默认格式 所以无需设置

实践例子 - 发送POST请求

上面的例子是查询员工信息,所以我们用的是GET请求,下面我们用一个创建员工的demo演示一下POST请求:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>创建员工信息</title>
</head>
<body>
  <h1>员工创建</h1>
  <label>请输入员工姓名:</label>
  <input type="text" id="staffName" /><br>
  <label>请输入员工编号:</label>
  <input type="text" id="staffNumber" /><br>
  <label>请选择员工性别:</label>
  <select id="staffSex">
    <option>男</option>
    <option>女</option>
  </select><br>
  <label>请输入员工职位:</label>
  <input type="text" id="staffJob" /><br>
  <button id="save">保存</button>
  <p id="createResult"></p>
  
  <script>
    document.getElementById("save").onclick = function(){
      var request = new XMLHttpRequest();
      request.open("POST","test.php");
      // 设置HTTP请求头信息,它告诉浏览器要发送一个表单信息
      request.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
      // 将表单信息拼接成URL参数形式,用 & 将参数隔开 传递给服务器
      var data = "name=" + document.getElementById("staffName").value
                  + "&number=" + document.getElementById("staffNumber").value
                  + "&sex=" + document.getElementById("staffSex").value
                  + "&job=" + document.getElementById("staffJob").value;
      request.send(data);
      request.onreadystatechange = function(){
        if(request.readyState === 4){
          if(request.status === 200){
            document.getElementById("createResult").innerHTML = request.responseText;
          }else{
            alert("发生错误" + request.status)
          }
        }
      }
    }
  </script>
</body>
</html>


POST请求和GET请求不一样,它的参数对用户是不可见的,所以不是用URL传参的形式,它是调用send()方法的时候将参数传递给服务器;我们可以先获取所有要传递参数的值,然后拼接成URL参数的形式赋值给data变量,send(data)方法调用的时候传递data的值即可。

兼容IE6和IE5以下版本

if(window.XMLHttpRequest){
  request = new XMLHttpRequest();
}else if(window.ActiveXObject){
  request = new ActiveXObject("Microsoft.XMLHTTP");
}

tips: 如果你开发的网站需要兼容IE6一下版本才需要加这段代码,若不需要则忽略;

获取JSON格式数据

上面的例子我们都是用XHR对象的responseText属性获取服务器返回的字符串数据,返回几段文字还好,当服务器返回大量数据的时候,我们处理起来就非常麻烦了。当然,我们也可以用responseXML属性获取XML格式的数据,但是现在2018年了!我们该换一下新东西了。

JSON是一种轻量级的数据交换格式,易于人阅读和编写。在 JS 语言中,一切都是对象。因此,任何支持的类型都可以通过 JSON 来表示,例如字符串、数字、对象、数组等。

JSON是用键值对来表示的,首先一个大括号包裹,键/值对组合中的键名写在前面并用双引号 "" 包裹,使用冒号 : 分隔,然后紧接着值:
{"firstName": "Json"}

var obj = {a: 'Hello', b: 'World'}; //这是一个对象,注意键名也是可以使用引号包裹的
var json = '{"a": "Hello", "b": "World"}'; //这是一个 JSON 字符串,本质是一个字符串

要实现从对象转换为 JSON 字符串,使用 JSON.stringify() 方法:
var json = JSON.stringify({a: 'Hello', b: 'World'}); //结果是 '{"a": "Hello", "b": "World"}'  
  
要实现从 JSON 转换为对象,使用 JSON.parse() 方法:
 var obj = JSON.parse('{"a": "Hello", "b": "World"}'); //结果是 {a: 'Hello', b: 'World'}

更详细的JSON资料请自行查阅相关资料。

使用方法:

// 实例化一个ajax对象
var request = new XMLHttpRequest();

// 调用HTTP请求,获取输入框内的值作为查询参数传递给服务器
request.open("GET","test.php?number=" + document.getElementById("keyword").value);

requset.send(); // 发送请求
// 监听服务器处理状态
requset.onreadystatechange = function(){
    if(requset.readyState ===4){
        if(requset.status === 200){
            // 将服务器返回的JSON数据转换为js对象
            var = JSON.parse(requset.responseText);
            // 判断请求是否成功(success的值是否为true),data.success的值是后端返回给我们的
            if(data.success){
                console.log(data)
            }else{
                alert("发生错误:" + data.msg)
            }
        }
    }
}

image.png
看到这里,说明你应该理解的差不多了,记得多动手去写代码,这样理解和掌握起来更快!

文章分类
热门文章
文章标签