14

Ajax学习与理解

想要学习的Ajax内容都在这个教程阮一峰javascript--XMLHttpRequest 对象
应该注意的点

  1. JS 是一门语言,JSON 是另一门语言,JSON 这门语言抄袭了 JS这门语言
  2. AJAX 就是用 JS 发请求
  3. 响应的第四部分是字符串,可以用 JSON 语法表示一个对象,也可以用 JSON 语法表示一个数组,还可以用 XML 语法,还可以用 HTML 语法,还可以用 CSS 语法,还可以用 JS 语法,还可以用我自创的语法

1 如何发请求?

用 form 可以发请求,但是会刷新页面或新开页面
用 a 可以发 get 请求,但是也会刷新页面或新开页面
用 img 可以发 get 请求,但是只能以图片的形式展示
用 link 可以发 get 请求,但是只能以 CSS、favicon 的形式展示
用 script 可以发 get 请求,但是只能以脚本的形式运行

<form action="xxx" method="POST">
  <input type="text" name="password">
  <input type="submit">
</form>

使用form发送请求,查看请求的内容
Pdt4Cq.png
password=123456就是POST请求的第四部分

那有没有什么方式可以实现

  1. get、post、put、delete 请求都行
  2. 想以什么形式展示就以什么形式展示

2 微软的突破

IE 5 率先在 JS 中引入 ActiveX 对象(API),使得 JS 可以直接发起 HTTP 请求(想用getpost都可以,想以什么形式展示就以什么形式展示)。
随后 Mozilla、 Safari、 Opera 也跟进(抄袭)了,取名 XMLHttpRequest(全局对象),并被纳入 W3C 规范

XMLHttpRequest使得浏览器有了和软件一样的体验,不局限于看文章和刷新

3 AJAX

Jesse James Garrett 讲如下技术取名叫做 AJAX:异步的 JavaScript 和 XML

  1. 使用 XMLHttpRequest 发请求
  2. 服务器返回 XML 格式的字符串(因为当时XML在当时是流行的数据传输格式,后来用json)
  3. JS 解析 XML,并更新局部页面
2005年2月,AJAX 这个词第一次正式提出,它是 Asynchronous JavaScript and XML 的缩写,指的是通过 JavaScript 的异步通信,从服务器获取 XML 文档从中提取数据,再更新当前网页的对应部分,而不用刷新整个网页。后来,AJAX 这个词就成为 JavaScript 脚本发起 HTTP 通信的代名词,也就是说,只要用脚本发起通信,就可以叫做 AJAX 通信。W3C 也在2006年发布了它的国际标准。

.

具体来说,AJAX 包括以下几个步骤。

  1. 创建 XMLHttpRequest 实例
  2. 发出 HTTP 请求
  3. 接收服务器传回的数据
  4. 更新网页数据

概括起来,就是一句话,**AJAX 通过原生的XMLHttpRequest对象发出 HTTP
请求,得到服务器返回的数据后,再进行处理。现在,服务器返回的都是 JSON** 格式的数据,XML 格式已经过时了,但是 AJAX
这个名字已经成了一个通用名词,字面含义已经消失了。

4 如何使用 XMLHttpRequest对象

所有代码都在这里
每一次大的更新可以查看commit
服务器端代码:

if(path === '/'){
    response.statusCode = 200
    let string = fs.readFileSync('./index.html') 
    response.setHeader('Content-Type', 'text/html;charset=utf-8')
    response.write(string)
    response.end()
  }

响应

对于响应来说,第四部分始终都是字符串,因为response.write(string)返回的是字符串,我们给浏览器返回了符合html格式的字符串.
然后再设置响应头中的Content-Type,response.setHeader('Content-Type', 'text/html;charset=utf-8'),即要求浏览器以HTML的语法解析这段字符串!,所以我们可以设置浏览器使用的解析方法为json,也可设置为xml.所以JSON 是一门语言!!

http请求的路径都是绝对路径.所以都是以/开头

4.1开始使用

所有代码都在这里
查看commit既有每次迭代的代码

我们请求一个以xml格式解析的字符串,然后看看响应是什么
服务器端代码

else if (path === '/xxx') {
    response.statusCode = 200
    response.setHeader('Content-Type', 'text/xml;charset=utf-8')
    response.write(`
    <note>
      <to>Tove</to>
      <from>Jani</from>
      <heading>Reminder</heading>
      <body>Don't forget me this weekend!</body>
    </note>
    `)
    response.end()
  }

main.js

let myButton = document.getElementById('myButton');
myButton.addEventListener("click",(e)=>{
    let request = new XMLHttpRequest();
    request.open('GET','/xxx')//配置request.参数分别为方法和路径
    request.send();//发送请求
})

index.html

<body>
    <button id="myButton">点我</button>
    <script src="main.js"></script>
</body>

当点击点我按钮时,查看发送的请求和收到的响应:
PdIUl6.png

我们将request打印出来,看看结构:
console.log(request)
PdIq10.png

4.1.2 理解j代码中的时间概念

XMLHttpRequest.readyState

XMLHttpRequest.readyState返回一个整数,表示实例对象的当前状态。该属性只读。
能够返回0,1,2,3,4,具体数字代表看上面的文档.
4,表示服务器返回的数据已经完全接收,或者本次接收已经失败
通信过程中,每当实例对象发生状态变化,它的readyState属性的值就会改变。这个值每一次变化,都会触发readyStateChange事件。
var xhr = new XMLHttpRequest();

if (xhr.readyState === 4) {
  // 请求结束,处理服务器返回的数据
} else {
  // 显示提示“加载中……”
}

上面代码中,xhr.readyState等于4时,表明脚本发出的 HTTP 请求已经成功。其他情况,都表示 HTTP 请求还在进行中。

下面我们从时间角度看看这个过程
PdonNd.png
当我们发送一个/xxx请求,使用的时间为9ms,9毫秒实际上很长,我们看一看在代码中9毫秒可以干什么
在控制台执行

console.time(); 
var a=1 ;  
console.timeEnd();

返回结果为default: 0.008056640625ms,声明一个变量只用了0.008ms

打印一句话只用了1ms
PdotEQ.png
所以9ms对于浏览器来说,对于代码来说是很长的,可以做很多事情.

接下来看看readyState属性在一次请求中的变化过程

let request = new XMLHttpRequest();
    request.open('GET','/xxx')
    request.send();
    setInterval(()=>{//在发送请求的过程中,每一毫秒问一下
        console.log(request.readyState);
    },1)

结果为:
Pdo259.png

readyState在这个过程中从1变为4
readyState各个值的含义
PdLVDP.png
刚刚只显示了1和4的原因是因为2,3太快,比一毫秒还快

01234这四个状态是逐个经过的
我们只需要记住4,4代表请求已经把响应下载完毕了

4.1.3 XMLHttpRequest.onreadystatechange

XMLHttpRequest.onreadystatechange = callback;

当 readyState 的值改变的时候,callback 函数会被调用。

例子:

var xhr= new XMLHttpRequest(),
    method = "GET",
    url = "https://developer.mozilla.org/";

xhr.open(method, url, true);
xhr.onreadystatechange = function () {
  if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
    console.log(xhr.responseText)
  }
}
xhr.send();

XMLHttpRequest.DONE就是4

onreadystatechange测试
把监听函数往上写,这样就不会错过每一个readyState的变化

myButton.addEventListener("click",(e)=>{
    let request = new XMLHttpRequest();
    request.onreadystatechange = ()=>{//把监听函数往上写,这样就不会错过每一个readyState的变化
        console.log(request.readyState);
    }
    request.open('GET','/xxx')//配置request.参数分别为方法和路径
    request.send();//发送请求
    // console.log(request)
})

打印结果为1,2,3,4
4代表请求已经把响应下载完毕了,但是请求成功和失败还要看status状态码是大于200小于300还是大于400

 request.onreadystatechange = ()=>{
        if(request.readyState ===4){
            console.log("请求和响应都完毕了");
            if ( request.status>=200&&request.status<=400){
                console.log('说明请求成功');
                console.log(request.responseText);//打印响应的第四部分,字符串
            }else if(request.status>=400){
                console.log("响应失败");
            }
        } 
    }

PdOwo8.png
但是xml结构不方便,需要使用DOMapi去获取数据.现在使用json

4.1.4 使用json解析响应的第四部分

什么是json:
json是一门数据格式化语言,用来表示数据
https://www.json.org/
轨道图

js与json的区别:
PdXk0P.png
以下都是合法的json语法:

"hi"
null
["a","b"]
{"name":"马涛涛","isBoy":true}
下面不符合!
{'x':"y"}
必须双引号

接下来我们返回一个符合json语法的字符串

else if (path === '/xxx') {
    response.statusCode = 200
    response.setHeader('Content-Type', 'text/xml;charset=utf-8')
    response.write(`
    {
      "note":{
        "from":"mataotao",
        "to":"ni",
        "bool":true,
        "arr":["a",1,2,3],
        "num":3
      }
    }
    `)
    response.end()

PdjmE6.png

使用window.JSON这个API,把符合json语法的字符串转化为js对应的值
这个API就像window.document.getElementById一样,是浏览器提供的api
修改一下main.js将json转化为

if ( request.status>=200&&request.status<=400){
                console.log('说明请求成功');
                console.log(request.responseText);
                console.log( typeof request.responseText);//string

                let string = request.responseText;
                //把符合json语法的字符串转化为js对应的值
                let object2 = window.JSON.parse(string);
                console.log( typeof object2)
                console.log(object2)
            }

PdjOPO.png

这样我们就可以用object.note.from取到"mataotao"这个字符串

http响应第四部分永远是字符串,知识写的这个字符串刚好符合json对象的语法

面试问题:请使用原生JS发送Ajax请求

一般面试大概率会问这个问题,写不对一定过不了面试

下面四句代码一定要记住:

myButton.addEventListener("click",(e)=>{
//这四句一定要记住
    let request = new XMLHttpRequest();
    request.onreadystatechange = ()=>{
    if(request.readyState === XMLHttpRequest.DONE && request.status === 200) {
    console.log(request.responseText)
  }
    }
    request.open('GET','/xxx')//配置request.参数分别为方法和路径
    request.send();//发送请求
//这四句一定要记住
})

风彻
1.5k 声望142 粉丝

« 上一篇
JSONP原理