概念


**Ajax  **(Async JavaScript & XML) 异步的JS和XML

最先由微软发明,Google搜索在首页上使用Ajax做搜索关键词建议后,Ajax就广泛应用起来了。

XML数据量偏大、解析相对困难、性能差。后来大家就转向JSON,但Ajax的名字没有变

**XHR   **xmlHttpRequest

向服务器端发起一个网络请求,并从服务器获得响应,XHR完全将HTTP开放给程序员使用

Ajax项目文件结构

上图是项目文件结构,需要安装Node.js、npm和express插件、body-parser插件、multer插件。

**项目中的内容**

**index.html**

1. <!DOCTYPE html>
2. <html lang="en">
3. <head>
4.     <meta charset="UTF-8">
5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
6.     <meta http-equiv="X-UA-Compatible" content="ie=edge">
7.     <title>XHR网络请求</title>
8. </head>
9. <body>
10.     <input type="text">
11.     <!-- <script src="index.js"></script> -->
12.       <script src="post.js"></script>
13.      <!-- <script src="formDate.js"></script>  -->
14. </body>
15. </html>

**index.js**

1. var xhr = new XMLHttpRequest()
2. // 创建一个xhr对象 后面将使用这个对象发起网络请求
3. // 当请求被发送到服务器时,我们需要执行一些基于响应的任务。
4. // 每当 readyState 改变时,就会触发 onreadystatechange 事件。
5. // readyState 属性存有 XMLHttpRequest 的状态信息。
6. xhr.onreadystatechange = function(ev){
7.     switch(xhr.readyState){
8.         case 0:
9.         console.log('未打开')
10.         break;
11.         case 1:
12.         console.log('服务器链接已建立')
13.         break;
14.         case 2:
15.         console.log('请求已接收')
16.         break;
17.         case 3:
18.         console.log('请求已处理')
19.         break;
20.         case 4:
21.         console.log('请求已完成')
22.         console.log(xhr.status)
23.         // 状态码
24.         console.log(xhr.statusText)
25.         // 状态描述
26.         console.log(xhr.responseText)
27.         // 响应文本
28.         console.log(xhr.responseType)
29.         // 响应类型
30.         console.log(xhr.getResponseHeader('Date'))
31.         // getResponseHeader获取指定的响应头信息
32.         console.log(xhr.getAllResponseHeaders())
33.         // getAllResponseHeaders获取所有的响应数据
34.
35.         break;
36.
37.     }
38. }
39.
40. xhr.open('GET','/comment?petname=wangBaoQiang&score=5&content=速度很快质量也不错')
41. // 设置请求方法 请求地址 及是否使用异步方式发起请求
42. xhr.send()

**post.js**

1. var xhr = new XMLHttpRequest()
2.
3. xhr.onreadystatechange = function(){
4.     if(xhr.readyState == 4){
5.         console.log(xhr.responseText)
6.     }
7. }
8.
9. xhr.open('POST','/comment')
10.
11. xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
12. // 如果向服务端发送的数据是urlencode 需要设置Content-Type请求头
13. // 如果不设置某些服务器可能无法正常解析收到数据
14. xhr.send('petname=wangBaoQiang&score=5&content=速度很快质量也不错')
15. // 向服务端发送数据

**formDate.js**

1. var data = new FormData()
2. data.append('petname','王宝强')
3. data.append('score',5)
4. data.append('content','服务态度很好')
5.
6. var xhr = new XMLHttpRequest()
7. xhr.onreadystatechange = function(){
8.     if(xhr.readyState == 4){
9.         console.log('请求完成')
10.         console.log(xhr.responseText)
11.
12.     }
13. }
14.
15. xhr.open('POST','http://127.0.0.1:3000/comment',true)
16.
17. xhr.send(data)
18. console.log('我是否等待 直到网络请求完成')
19. // 第三个参数指定使用同步完成请求或异步请求
20. // 默认是true即异步请求
21. // 改为false可以变成同步请求 同步请求造成页面卡死直到请求完成
22. // 通常会影响用户体验 不建议使用
23. // Ajax
24. // Async JavaScript and XMl
25. // 异步:不等待其它条件具备就继续执行代码
26. // 同步:等待条件后才继续执行代码

**后端文件index.js**

1. const exp = require('express')
2. const bodyParser = require('body-parser')
3. const multer = require('multer')
4. // multer模块可以处理以formData形式提交的数据
5. // 还可以处理上传文件
6. const app = exp()
7. const form = multer()
8.
9. app.use(exp.static('public'))
10. app.use(bodyParser.urlencoded({extended:true}))
11.
12. app.get('/comment',(req,res)=>{
13.   console.log('收到get请求' + JSON.stringify(req.query))
14.   res.status(200).send('谢谢你的评价')
15. })
16. // 第二个参数form.array()在正式处理请求之前处理以formDara
17. // 方式提交的数据 如果发现是以formdata提交的数据 
18. // 会把这些数据取出来放入req.body中
19.
20. app.post('/comment',form.array(),(req,res)=>{
21.     'use strict'  //严格模式
22.      console.log(req.body)
23.     console.log(req.originalUrl)
24.
25.     console.log('cc' + req.route)
26.     // console.log(userAgent)
27.     // 使用let声明变量时 不能提前使用这个变量会报错
28.     // let相当于var let的限制比var大 代码出错的可能性更小
29.     let userAgent = req.get('User-Agent')
30.     console.log(userAgent)
31.
32.     console.log('用户语言偏好' + req.get('Accept-Language'))
33.     console.log('收到post请求' + JSON.stringify(req.body))
34.     res.header('Access-Control-Allow-Origin','*')
35.     // 解决跨域 设置Access-Control-Allow-Origin:*
36.     // 表示允许任何域名跨域访问
37.     // setTimeout延迟执行一段代码 是异步的 它不会等待延迟的代码
38.     setTimeout(function() {
39.         res.status(200).send('感谢你的光临')
40.     }, 10*1000);
41. })
42. app.listen(3000,function(){
43.     console.log('服务器运行了')
44. })
45. // 总结 使用xhr发送请求 xhrhttprequest
46. //     请求行:
47. //       包括请求方法和url
48. //       xhr.open()
49. //     请求头:
50.         // xhr.setRequestHeader('name','value')
51.         // 设置请求头之后必须在xhr.open()方法之后调用
52.     //    空行:
53.     //      不需要控制
54.     //   请求体:
55.     //    xhr.send()
56.     // 在服务端获取请求数据
57.     //   请求行:
58.     //    获取请求方法  req.route
59.     //    获取URl  req.originalUrl
60.     //    获取url中的数据 req.query.name
61.     //   请求头:
62.     //     获取请求头 req.get('name')
63.     //   请求体
64.     //     获取请求体中的数据 req.body.name
65.     //     如果数据是urlencode  body-parser 模块
66.     //     如果数据格式是multipart\formdata  multer模块
67.
68.     //  在Node.js中获取响应数据
69.     //  响应行: 设置状态吗 res.status
70.     //  响应头:设置响应头 res.set(name,value)
71.     //  响应体:
72.     //     添加响应体 res.append()
73.     //     结束响应体 res.end()
74.     //     设置响应头 res.send(',,,')
75.     //        JSON    resizeBy.json({})
76.
77.     // 使用xhr获取响应数据
78.     // 在哪获取响应数据
79.     //  设置onreadystatechange回调函数
80.     //  当readystate == 4 可以获取响应数据
81.     //  响应行:
82.     //   状态码  xhr.status
83.     //   状态信息: xhr.statusText
84.     //   响应头 xhr.getResponseHeader
85.     //   获取所有响应头 xhr.getAllResponseHeaders
86.     //   响应体
87.     //   xhr.response
88.     //   xhr.responseText
89.     //   xhr.responseXML
90.
91.