# AJAX
## 1.原生AJAX
### 1.1AJAX简介
AJAX 全称为 Asynchronous JavaScript And XML,就是异步的 JS 和 XML。
通过 AJAX 可以在浏览器中向服务器发送异步请求,最大的优势:==无刷新获取数据==。
AJAX 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。
### 1.2XML简介
XML 可扩展标记语言。
XML 被设计用来传输和存储数据。
XML 和 HTML 类似,不同的是 HTML 中都是预定义标签,而 XML 中没有预定义标签,
> ``` xml
> 比如说我有一个学生数据:
> name = "孙悟空" ; age = 18 ; gender = "男" ;
> 用 XML 表示:
> <student>
> <name>孙悟空</name>
> <age>18</age>
> <gender>男</gender>
> </student>
> ```
### 1.3AJAX的特点
#### 1.3.1AJAX的优点
+ 可以无需刷新页面而与服务器端进行通信
+ 允许你根据用户事件来更新部分页面内容
#### 1.3.2AJAX的缺点
- 没有浏览历史,不能回退
- 存在跨域问题(同源)
- SEO 不友好
#### 1.3.3AJAX的一般使用场景
搜索栏,(搜索栏输入一个值,在下面出现一系列值)
注册页面,
淘宝页面(用户点击,向服务器发请求,返回请求,出现效果)等网页
#### 1.3.4使AJAX技术得到实现的技术
* XMLHttpRequest(XHR)对象
* axios
* Fetch技术
* JSONP
#### 1.3.5需要了解的其他知识
1.HTTP协议,以及如何在游览器中怎么查看里面的一些属性
2. 用户事件
3. SEO
4.关于POST和GET的区别(POST方式的请求体可以为空,GET方式的请求体为空)
5.关于怎么解决跨域的问题
## 2.使用XHR来实现AJAX
### 2.1前提知识
#### 2.1.1XHR的readyState属性
有5个值,用于表示当前处在请求、响应过程的那个阶段
| 0 | 未初始化。尚未调用open()方法 |
| ---- | :-------------------------------------------------- |
| 1 | 已打开(Open) 已调用open()方法,尚未调用send()fangfa |
| 2 | 已发送(Sent)。已调用send()方法,尚未收到响应 |
| 3 | 接收中(Receiving).已经收到部分响应 |
| 4 | 完成(Complete)已经收到所有的响应,可以使用 |
#### 2.1.2常见的状态响应码(status)
```sql
1xx:指示信息--表示请求已接收,继续处理
2xx:成功--表示请求已被成功接收、理解、接受
3xx:重定向--信息不完整需要进一步补充
4xx:客户端错误--请求有语法错误或请求无法实现
5xx:服务器端错误--服务器未能实现合法的请求
200 交易成功
400 错误请求,如语法错误
403 禁止访问
404 没有发现文件、查询或URL
500 内部服务器错误
```
详情了解可参考[状态响应码](http://t.csdn.cn/JGTqx)
#### 2.1.3利用express搭建一个简单的服务器
### 2.2开始实现
#### 2.2.1搭建一个简单的服务器
> ```javascript
> const express = require('express');
> const app = express();
>
> app.get('/server', (request, response) => {
> //设置响应头 设置允许跨域
> response.setHeader('Access-Control-Allow-Origin', '*');
> //设置响应体
> response.send('HELLO AJAX - 2');
> });
> //4. 监听端口启动服务
> app.listen(8000, () => {
> console.log("服务已经启动, 8000 端口监听中....");
> })
> 开启8000端口的服务器,用与客户端向其发送请求
> ```
#### 2.2.2GET方式
> ```javascript
> <style>
> #result{
> width:200px;
> height:100px;
> border:solid 1px #90b;
> }
> </style>
> <button>点击发送请求</button>
> <div id="result"></div>
> ```
> <script>
> //获取button元素
> const btn = document.getElementsByTagName('button')[0];
> const result = document.getElementById("result");
> //绑定事件
> btn.onclick = function(){
> //1. 创建对象
> const xhr = new XMLHttpRequest();
> //2. 初始化 设置请求方法和 url
> xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200&c=300');
> //3. 发送
> xhr.send();
> //4. 事件绑定 处理服务端返回的结果
> // on when 当....时候
> // readystate 是 xhr 对象中的属性, 表示状态 0 1 2 3 4
> // change 改变
> xhr.onreadystatechange = function(){
> //判断 (服务端返回了所有的结果)
> if(xhr.readyState === 4){
> //判断响应状态码 200 404 403 401 500
> // 2xx 成功
> if(xhr.status >= 200 && xhr.status < 300){
> //处理结果 行 头 空行 体
> //响应
> // console.log(xhr.status);//状态码
> // console.log(xhr.statusText);//状态字符串
> // console.log(xhr.getAllResponseHeaders());//所有响应头
> // console.log(xhr.response);//响应体
> //设置 result 的文本
> result.innerHTML = xhr.response;
> }else{
> }
当点击按钮时(先开启服务器代码,进入到服务器代码的目录中使用 node -xxx.js)



#### 2.2.3POST方式
与前面代码相似:
> ``` javascript
> xhr.open('POST', 'http://127.0.0.1:8000/server');
> //设置请求头
> xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
> xhr.setRequestHeader('name','atguigu');
> //3. 发送
> xhr.send('a=100&b=200&c=300');
> ```
>
> POST方式可携带参数,server.js中修改`response.send('HELLO AJAX POST')`


#### 2.2.4 你也可以设置服务器端发送代码的数据形式!g
> ``` javascript
> const data = {
> name: 'atguigu'
> };
> //对对象进行字符串转换
> let str = JSON.stringify(data);
> //设置响应体
> response.send(str);
> ```
> ``` javascript
> 1. 手动对数据转化
> let data = JSON.parse(xhr.response)
> console.log(data);
> result.innerHTML = data.name;
> 2. 自动转换
> //设置响应体数据的类型
> xhr.responseType = 'json';(在xhr.onreadystatechange之前)
> console.log(xhr.response);
> result.innerHTML = xhr.response.name;
> ```

#### 2.2.5解决IE缓存的问题
IE缓存问题:就是在客户端向服务器发送请求,第一次请求正常,第二次
显示的结果为第一次的结果。这是因为IE==走的是缓存==。
解决方法:
可在请求的url后面添加Date.now()(时间戳)
eg:` xhr.open("GET",'http://127.0.0.1:8000/ie?t='+Date.now());`
#### 2.2.6关于超时和网络异常时数据显示的效果
> ``` javascript
> setTimeout(() => {
> //设置响应体
> response.send('延时响应');
> }, 3000)
> 服务器端修改
> ```
客户端修改
> ``` javascript
> //超时设置 2s 设置
> xhr.timeout = 2000;
> //超时回调
> xhr.ontimeout = function(){
> alert("网络异常, 请稍后重试!!");
> }
> /网络异常回调
> xhr.onerror = function(){
> alert("你的网络似乎出了一些问题!");
> }
> ```
此时弹出弹框显示=="网络异常, 请稍后重试!!==
当你==设置网络==为断网时弹框显示==“你的网络似乎出了一些问题!”==
在network中下的Oline选项选择offline(设置断网)
## 3.使用 jQuery方式实现
jQuery有多种实现AJAX的属性
具体可参考jQuery官网[jQuery](https://jquery.com/)
### 3.1 jQuery的GET方法
服务器端代码(修改)前面的内容还是要的
> ``` javascript
> const data = {name:'尚硅谷'};
> response.send(JSON.stringify(data))
> ```
> ``` javascript
> $.get('http://127.0.0.1:8000/jquery-server', {a:100, b:200}, function(data){
> console.log(data);
> },'json');
> 数据输出形式为json形式
> ```
客户端代码
### 3.2 jQuery的POST方法
> ``` javascript
> $.post('http://127.0.0.1:8000/jquery-server', {a:100, b:200}, function(data){
> console.log(data);
> });
> ```
### 3.3 jQuery的通用方法
> ``` javascript
> $.ajax({
> //url
> url: 'http://127.0.0.1:8000/jquery-server',
> //参数
> data: {a:100, b:200},
> //请求类型
> type: 'GET',
> //响应体结果
> dataType: 'json',
> //成功的回调
> success: function(data){
> console.log(data);
> },
> //超时时间
> timeout: 2000,
> //失败的回调
> error: function(){
> console.log('出错啦!!');
> },
> //头信息
> headers: {
> c:300,
> d:400
> }
> });
> ```
