AJAX

AJAX 全称为 Asynchronous JavaScript And XML,就是异步的 JS 和 XML。 通过 AJAX 可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据 AJAX 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。

优缺点

优点

  • 可以无需刷新页面而与服务器端进行通信。
  • 允许你根据用户事件来更新部分页面内容。

缺点

1) 没有浏览历史,不能回退
2) 存在跨域问题(同源)
3) SEO 不友好

属性、方法

属性

  • readyState:Ajax状态码 *
    1 表示对象已建立,但未初始化,只是 new 成功获取了对象,但是未调用open方法
    2 表示对象已初始化,但未发送,调用了open方法,但是未调用send方法
    3 已调用send方法进行请求
    4 正在接收数据(接收到一部分),客户端已经接收到了一部分返回的数据
    5 接收完成,客户端已经接收到了所有数据 *
  • status:http响应状态码 200/300/400/500
  • statusText:http响应状态文本
  • responseText:如果服务器端返回字符串,使用responseText进行接收
  • responseXML:如果服务器端返回XML数据,使用responseXML进行接收
  • responseType:规定response数据类型
  • onreadystatechange:当 readyState 状态码发生改变时所触发的回调函数

方法

  • open(method,url,[aycs]):初始化Ajax对象 (打开)
    method:http请求方式,get/post
    url:请求的服务器地址
    aycs:同步与异步
  • setRequestHeader(header,value):设置请求头信息
    header:请求头名称
    value:请求头的值
  • xhr.getAllResponseHeaders() 获取全部响应头信息
  • xhr.getResponseHeader(‘key’) 获取指定头信息
  • send([content]) :发送Ajax请求
    1 content 如果是get请求时,此参数为null;
    2 content 如果是post请求时,此参数就是要传递的数据

注意: 所有相关的事件绑定必须在调用send()方法之前进行.

http协议

HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。

HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。

HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的规范化工作正在进行之中,而且HTTP-NG(Next Generation of HTTP)的建议已经提出。

HTTP协议工作于客户端-服务端架构为上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。Web服务器根据接收到的请求后,向客户端发送响应信息。

img

GET

<script>
    const btn = document.getElementById('button')
    const text = document.getElementById('text')
    btn.onclick=()=>{
      // 创建对象
       const xhr=new XMLHttpRequest()
      // 初始化设置方法和url
      xhr.open('GET','http://127.0.0.1:8001/server?a=1&&b=2&&c=3')
      //发送
      xhr.send()
      // 事件绑定处理服务器返回的结果
      // readystate 是xhr对象属性表示状态 0 1 2 3 4
      xhr.onreadystatechange = function(){
        // 判定服务器返回的所有结果
        if(xhr.readyState ===4){
          // 判定状态码 200 404 403 401 500
          if(xhr.status >=200 && xhr.status<300){
            // 处理结果 行 头 空行 体
            console.log(xhr.status) //状态码
            console.log(xhr.statusText) //状态字符串
            console.log(xhr.getAllResponseHeaders()) //所有响应头
            console.log(xhr.response) //响应体
            text.innerHTML=xhr.response
          }
        }
      }
    }
</script>

服务器端

app.get('/server',(request, response)=>{
  // 设置响应头,允许跨域
  response.setHeader('Access-Control-Allow-Origin','*')
  //  设置响应
  response.send('hello ,express ,get')
})

POST

<script>
    const text = document.getElementById('text')
    text.addEventListener('mouseover',()=>{
       // 创建对象
       const xhr=new XMLHttpRequest()
      // 初始化设置方法和url
      xhr.open('POST','http://127.0.0.1:8001/server')
      //发送
      xhr.send('a=1&b=2&c=3')
      // 设置请求头
      xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
      // 事件绑定处理服务器返回的结果
      // readystate 是xhr对象属性表示状态 0 1 2 3 4
      xhr.onreadystatechange = function(){
        // 判定服务器返回的所有结果
        if(xhr.readyState ===4){
          // 判定状态码 200 404 403 401 500
          if(xhr.status >=200 && xhr.status<300){
            // 处理结果 行 头 空行 体
            console.log(xhr.status) //状态码
            console.log(xhr.statusText) //状态字符串
            console.log(xhr.getAllResponseHeaders()) //所有响应头
            console.log(xhr.response) //响应体
            text.innerHTML=xhr.response
          }
        }
      }
    })
</script>

服务器端

app.post('/server',(request, response)=>{
  // 设置响应头,允许跨域
  response.setHeader('Access-Control-Allow-Origin','*')
  //  设置响应
  response.send('hello ,express ,post')
})

JSON

<script>
    const text = document.getElementById('text')

    window.onkeydown=function(){
       // 创建对象
       const xhr=new XMLHttpRequest()
      // 初始化设置方法和url
      xhr.open('GET','http://127.0.0.1:8001/json-server')
      //发送
      xhr.send()
      // JSON数据自动转换
      xhr.responseType='json'
      // 事件绑定处理服务器返回的结果
      // readystate 是xhr对象属性表示状态 0 1 2 3 4
      xhr.onreadystatechange = function(){
        // 判定服务器返回的所有结果
        if(xhr.readyState ===4){
          // 判定状态码 200 404 403 401 500
          if(xhr.status >=200 && xhr.status<300){
            // 处理结果 行 头 空行 体
            console.log(xhr.status) //状态码
            console.log(xhr.statusText) //状态字符串
            console.log(xhr.getAllResponseHeaders()) //所有响应头
            console.log(xhr.response) //响应体

            // // 手动对json数据转换
            // let data=JSON.parse(xhr.response)
            // text.innerHTML=data.name+","+data.age
            text.innerHTML=xhr.response.name+","+xhr.response.age
          }
        }
      }
    }
</script>

服务器端

app.all('/json-server',(request, response)=>{
  // 设置响应头,允许跨域
  response.setHeader('Access-Control-Allow-Origin','*')
  //  设置响应
  const data ={
    name:'zhangsan',
    age:'nan'
  }
  // 将对象对象进行字符串转换
  let str =JSON.stringify(data)
  response.send(str)
})

nodemon

nodemon 是一个工具,通过在检测到目录中的文件更改时自动重新启动节点应用程序来帮助开发基于 node.js 的应用程序。

npm install -g nodemon //安装并且 nodemon 将全局安装到您的系统路径。

请求超时和网络异常

 const xhr=new XMLHttpRequest()
      // 请求超时
      xhr.timeout=2000;
      //请求超时回调函数
      xhr.ontimeout=()=>{
        alert('请求超时,请等候')
      }
      //网络异常
      xhr.onerror=()=>{
        alert('网络异常,请等候')
      }
      xhr.open('GET','http://127.0.0.1:8001/delay')
      xhr.send()
      xhr.onreadystatechange = function(){
        if(xhr.readyState ===4){
          if(xhr.status >=200 && xhr.status<300){
            text.innerHTML=xhr.response
          }
        }
      }

服务端

app.get('/delay',(request, response)=>{
  // 设置响应头,允许跨域
  response.setHeader('Access-Control-Allow-Origin','*')
  //  设置响应
  setTimeout(() => {
    response.send('延迟显示');
  }, 3000);
})

取消请求

<script>
    const btn = document.querySelectorAll('button')
    let xhr=null
    btn[0].onclick=()=>{
      xhr=new XMLHttpRequest()
      xhr.open('GET','http://127.0.0.1:8001/delay')
      xhr.send()
    }
    btn[1].onclick=()=>{
      //取消请求
      xhr.abort()
    }
</script>

请求重复

<script>
    const btn = document.getElementById('button')
    let xht=null
    let isSending = false //是否正在发生ajax请求
    btn.addEventListener('click',()=>{
      if(isSending) xhr.abort(); //如果正在发送,取消该请求
      xhr=new XMLHttpRequest()
      isSending = true //修改变量
      xhr.open('GET','http://127.0.0.1:8001/delay')
      xhr.send()
      xhr.onreadystatechange = function(){
        if(xhr.readyState ===4){
            isSending = false
        }
      }
    })
</script>

uTools_1645516240122

jQuery

<SCript>
  // get
    $('button').eq(0).click(()=>{
      $.get('http://127.0.0.1:8001/jquery-server',{a:100,b:200},(data)=>{
        console.log(data)
      },'json')
    })
  //post
    $('button').eq(1).click(()=>{
      $.post('http://127.0.0.1:8001/jquery-server',{a:100,b:200},(data)=>{
        console.log(data)
      },'json')
    })
  //all
  $('button').eq(2).click(()=>{
      $.ajax({
        url:'http://127.0.0.1:8001/jquery-server',
        data:{a:100,b:200},
        type:'post',
        dataType:'json',
        //成功回调
        success:(data)=>{
           console.log(data)
        },
        // 失败回调
        error:(data)=>{
           console.log("出错了")
        },
        // 超时时间
        timeout:2000,
        // 头信息
        headers:{
          a:300,
          b:400
        }
      })
    })
</SCript>

服务端

//jquery请求
app.all('/jquery-server',(request, response)=>{
  response.setHeader('Access-Control-Allow-Origin','*')
  const data ={name:'zs'}
  let str =JSON.stringify(data)
  response.send(str)
})

Axios

<SCript>
  // get
  const btns=document.querySelectorAll('button')

  axios.defaults.baseURL='http://127.0.0.1:8001'
  btns[0].onclick=function(){
    axios.get('/axios-server',{
      params:{
        id:100,
        vip:7
      },
      Headers:{
        name:'user',
        age:22
      }
    }).then(value=>{
      console.log(value)
    })
  }
  //post
  btns[1].onclick=function(){
    axios.get('/axios-server',
    {
        use:'admin',
        pw:'123'
      }
    ,{
      params:{
        id:100,
        vip:7
      },
      Headers:{
        name:'user',
        age:22
      },
    }).then(value=>{
      console.log(value)
    })
  }
  //all
  btns[2].onclick=function(){
  axios({
     method: 'get',
     url: '/axios-server',
     }).then((response)=> {
        console.log(response)
     });

  }
 
</SCript>

服务的

//axios请求
app.all('/axios-server',(request, response)=>{
  response.setHeader('Access-Control-Allow-Origin','*')
  const data ={name:'zs'}
  let str =JSON.stringify(data)
  response.send('hello,ajax')
})

fetch函数

<script>
        //文档地址
        //https://developer.mozilla.org/zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/fetch
        
        const btn = document.querySelector('button');

        btn.onclick = function(){
            fetch('http://127.0.0.1:8001/fetch-server?vip=10', {
                //请求方法
                method: 'POST',
                //请求头
                headers: {
                    name:'zs'
                },
                //请求体
                body: 'username=admin&password=admin'
            }).then(response => {
                // return response.text();
                return response.json();
            }).then(response=>{
                console.log(response);
            });
        }
    </script>

JSONP

JSONP 是什么 JSONP(JSON with Padding),是一个非官方的跨域解决方案,纯粹凭借程序员的聪明 才智开发出来,只支持 get 请求。

JSONP 怎么工作的? 在网页有一些标签天生具有跨域能力,比如:img link iframe script。 JSONP 就是利用 script 标签的跨域能力来发送请求的

1.动态的创建一个 script 标签
var script = document.createElement("script");
2.设置 script 的 src,设置回调函数
script.src = "http://localhost:3000/testAJAX?callback=abc";
function abc(data) {
alert(data.name);
};
3.将 script 添加到 body 中
document.body.appendChild(script);
4.服务器中路由的处理
router.get("/testAJAX" , function (req , res) {
console.log("收到请求");
var callback = req.query.callback;
var obj = {
    name:"孙悟空", age:18
}
res.send(callback+"("+JSON.stringify(obj)+")");
});

jQuery 中的 JSONP

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button id="btn">按钮</button>
<ul id="list"></ul>
<script type="text/javascript" src="./jquery-1.12.3.js"></script>
<script type="text/javascript">
window.onload = function () {
var btn = document.getElementById('btn')
btn.onclick = function () {
$.getJSON("http://api.douban.com/v2/movie/in_theaters?callback=?",function
(data) {
console.log(data);
//获取所有的电影的条目
var subjects = data.subjects;
//遍历电影条目
for(var i=0 ; i<subjects.length ; i++){
$("#list").append("<li>"+
subjects[i].title+"<br />"+
"<img src=\""+subjects[i].images.large+"\" >"+
"</li>");
}
});
}
}
</script>
</body>
</html>

CORS

CORS 是什么? CORS(Cross-Origin Resource Sharing),跨域资源共享。

CORS 是官方的跨域解决方 案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持 get 和 post 请求。跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些 源站通过浏览器有权限访问哪些资源

CORS 怎么工作的? CORS 是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应 以后就会对响应放行。

CORS 的使用
主要是服务器端的设置:
router.get("/testAJAX" , function (req , res) {
//通过 res 来设置响应头,来允许跨域请求
//res.set("Access-Control-Allow-Origin","http://127.0.0.1:3000");
res.set("Access-Control-Allow-Origin","*");
res.send("testAJAX 返回的响应");
});