Ajax学习笔记

Ajax学习笔记

1.Ajax简介

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

2.Ajax的优缺点

优点:

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

缺点:

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

3.Ajax的使用

3.1 创建一个项目

  • 新建文件夹-myCode;

  • 创建子文件server.js(使用express创建一个服务);

  • 创建index.html(用来实现Ajax页面的请求操作)

  • 初始化项目-npm init -y;

  • 下载依赖-npm i express nodemon;

    nodemon:可以自动启动应用服务;实时监测我们创建的服务;

3.2 server.js文件代码

const express = require('express');

const app = express();

app.get('/server', (req, res) => {
  // 设置响应头 允许跨域
  res.setHeader('Access-Control-Allow-Origin', '*');
  // 发送响应报文  send中只能放string及buffer类型数据
  setTimeout(() => {
  // 发送响应报文
  let data ={ name:'bbb' };
  res.send(JSON.stringify(data));
  }, 2000); //设置延迟响应
})

// all - 表示可以接收任意类型的请求(使用all是因为在方法中设置了自定义的请求头,如果没有可以使用post)
app.all('/server-all', (req, res) => {
  // 设置响应头 允许跨域
  res.setHeader('Access-Control-Allow-Origin', '*');
  //  设置响应头 允许所有预定义及自定义的请求头
  res.setHeader('Access-Control-Allow-Headers', '*');
  // 发送响应报文
  res.send('HELLO POST EXPRESS!')
})

app.listen('8000', () => {
  console.log('8000端口已启动!')
})

3.3 index.html文件代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Express</title>
  <style>
    #myform {
      margin: 20px 0;
    }

    #box {
      width: 200px;
      height: 200px;
      margin: 20px 0;
      border: 1px solid pink;
    }
  </style>
</head>

<body>
  <div id="app">
    <form action="" method="post" id="myform">
      姓名:<input type="text" name="name" value="zbt">
      密码:<input type="password" name="password" value="123456">
    </form>
    <button>发送GET请求</button>
    <button>取消GET请求</button>
    <button>发送POST请求</button>
    <div id="box"></div>
  </div>
  <script>
    let xhr = null; //后边如果需要使用,则把变量从函数中提出来
    // 获取表单元素
    let form = document.querySelector('#myform')
    // 获取按钮元素
    let btn = document.getElementsByTagName('button');
    // 获取box元素
    let box = document.getElementById('box');
    // 设置标识的变量,表示是否已经向服务器发送请求
    // 解决重复发送请求的问题
    let isSending = false;
    // 按钮点击-发送get请求
    btn[0].onclick = function () {
      if (isSending) { xhr.abort() }; //如果正在发送请求,则取消该请求并创建一个新的请求
      // 1.创建请求的对象
      // let xhr = new XMLHttpRequest();
      xhr = new XMLHttpRequest();
      // 创建完对象之后,表示已经开始准备发送请求,这时候设置变量为true
      isSending = true;
      // 设置xhr的响应类型是JSON,会自动处理响应的JSON数据(JSON.parse)
      xhr.responseType = 'json';
      // 超时设置,如果>=3秒则取消接口调用
      xhr.timeout = 3000;
      xhr.ontimeout = function () {
        alert('请求超时!')
      }
      xhr.onerror = function () {
        alert('网络中断!')
      }
      // 2.初始化,设置请求的方法和URL 
      // Date.now()-用来解决IE接口缓存问题(IE中接口会调用一次,剩下的访问都会从缓存中拿数据)
      xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200&t=' + Date.now());
      // 3.发送
      xhr.send();
      // 4.时间绑定,处理服务器返回的结果
      /*
      * on - 当什么时候
      * readyState - xhr的属性表示状态
      *   0: 表示 XMLHttpRequest 实例已经生成,但是 open()方法还没有被调用。
      *   1: 表示 send()方法还没有被调用,仍然可以使用 setRequestHeader(),设定 HTTP请求的头信息。
      *   2: 表示 send()方法已经执行,并且头信息和状态码已经收到。
      *   3: 表示正在接收服务器传来的 body 部分的数据。
      *   4: 表示服务器数据已经完全接收,或者本次接收已经失败了
      * change - 改变 会改变4次:0-1 1-2 2-3 3-4
      * onreadystatechange - 检测当状态改变时
      */
      xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
          isSending = false;
          // status - 状态码 2开头的表示成功
          if (xhr.status >= 200 && xhr.status < 300) {
            console.log(xhr.statusText) //状态字符串 'ok'
            console.log(xhr.getAllResponseHeaders()) //所有的响应头
            console.log(xhr.response); //响应体
            // box.innerHTML = xhr.response;
            // 手动解析JSON
            // box.innerHTML = JSON.parse(xhr.response).name;
            // 设置xhr.responseType = 'json'响应体类型为JSON后自动解析
            box.innerHTML = xhr.response.name;
          }
        }
      }
    }
    //按钮点击-发送post请求
    btn[1].onclick = function () {
      xhr.abort();//取消函数调用
    }
    btn[2].onclick = function () {
      // 创建对象
      let xhr = new XMLHttpRequest();
      // 初始化 设置请求方式跟接口地址
      xhr.open('POST', 'http://127.0.0.1:8000/server-all');
      // 设置请求头 请求头名,值  设置请求体的类型
      //预定义的请求头
      // xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
      // 自定义的请求头
      xhr.setRequestHeader('name', '1234')
      // 发送 post请求需要在这设置请求体
      // xhr.send('a=100&b=200');
      // xhr.send('a:100&b:200');
      // xhr.send(123);
      // // let data = new FormData(form) //获取上面form表单中的数据
      let data = new FormData()
      data.append('name', 'zbt')
      data.append('password', 'hhh')
      xhr.send(data);
      // 处理返回结果
      xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
          if (xhr.status >= 200 && xhr.status < 300) {
            box.innerHTML = xhr.response;
          }
        }
      }
    }
  </script>
</body>

</html>

4.jQuery发送Ajax请求

4.1.get请求

$.get(url, [data], [callback], [type])

​ url:请求的 URL 地址。

​ data:请求携带的参数。

​ callback:载入成功时回调函数。

​ type:设置返回内容格式,xml, html, script, json, text, _default。

4.2post请求

$.post(url, [data], [callback], [type])

​ url:请求的 URL 地址。

​ data:请求携带的参数。

​ callback:载入成功时回调函数。

​ type:设置返回内容格式,xml, html, script, json, text, _default。

代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>jquery-Ajax</title>
  <!-- 引入bootstrap -->
  <link crossorigin="anonymous" href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css"
    rel="stylesheet">
  <!-- 引入jQuery -->
  <script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>

<body>
  <div id="app">
    <h2>jQuery发送Ajax请求</h2>
    <button class="btn btn-primary">get请求</button>
    <button class="btn btn-danger">post请求</button>
    <button class="btn btn-info">通用形方法请求</button>
  </div>
  <script>
    /**
     * 接口地址,请求参数,响应体函数,响应体类型
    */
    $('button').eq(0).click(function () {
      $.get('http://127.0.0.1:8000/jquery-ajax', { a: 100, b: 200 }, function (data) {
        // 打印出来是对象
        console.log(data)
      }, 'json')
    })
    $('button').eq(1).click(function () {
      $.post('http://127.0.0.1:8000/jquery-ajax', { a: 100, b: 200 }, function (data) {
        //  打印出来是字符串
        console.log(data)
      })
    })
    $('button').eq(2).click(function () {
      $.ajax({
        url: 'http://127.0.0.1:8000/jquery-ajax', //请求地址
        data: { a: 100, b: 200 }, //请求参数
        type: 'POST', //请求类型
        dataType: 'json', //响应体结果类型
        timeout: 2000, //超时时间
        headers: {}, //自定义的请求头
        success: function (data) { //成功的回调
          console.log(data)
        },
        error: function () {  //失败的回调

        }
      })
    })
  </script>
</body>

</html>

5.Axios发送Ajax请求

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>jquery-Ajax</title>
  <!-- 引入bootstrap -->
  <link crossorigin="anonymous" href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css"
    rel="stylesheet">
  <!-- 引入Axios -->
  <script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/0.19.2/axios.js"></script>
</head>

<body>
  <div id="app">
    <h2>Axios发送Ajax请求</h2>
    <button class="btn btn-primary">get请求</button>
    <button class="btn btn-danger">post请求</button>
    <button class="btn btn-info">通用形方法请求</button>
  </div>
  <script>
    const btn = document.getElementsByTagName('button');
    // 配置请求token
    // axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
    // 配置请求头
    axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
    //配置 baseURL
    axios.defaults.baseURL = 'http://127.0.0.1:8000';

    btn[0].onclick = function () {
      axios.get('/axios-ajax', {
        params: { //请求参数
          a: 100,
          b: 200
        },
        headers: { //自定义请求头
          name: 123
        }
      }).then((response) => {
        // 响应内容
        console.log(response)
      }).catch(function (error) {
        console.log(error);
      });
    }

    btn[1].onclick = function () {
      axios.post('/axios-ajax', { //请求体参数
        username: 'admin',
        password: 'admin'
      }, {
        params: { //url请求参数
          a: 100,
          b: 200
        },
        //请求头参数
        headers: {
          height: 180,
          weight: 180,
        }
      });
    }

    btn[2].onclick = function () {
      axios({
        //请求方法
        method: 'POST',
        //url
        url: '/axios-ajax',
        //url参数
        params: {
          vip: 10,
          level: 30
        },
        //头信息
        headers: {
          a: 100,
          b: 200
        },
        //请求体参数
        data: {
          username: 'admin',
          password: 'admin'
        }
      }).then(response => {
        //响应状态码
        console.log(response.status);
        //响应状态字符串
        console.log(response.statusText);
        //响应头信息
        console.log(response.headers);
        //响应体
        console.log(response.data);
      })
    }
  </script>
</body>

</html>

6.fetch发送Ajax请求

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>fetch 发送 AJAX请求</title>
</head>
<body>
    <button>AJAX请求</button>
    <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:8000/fetch-ajax?vip=10', {
                //请求方法
                method: 'POST',
                //请求头
                headers: {
                    name:'atguigu'
                },
                //请求体
                body: 'username=admin&password=admin'
            }).then(response => {
                // return response.text();
                return response.json();
            }).then(response=>{
                console.log(response);
            });
        }
    </script>
</body>
</html>

7.JSONP实践练习

原理:

​ 在网页有一些标签天生具有跨域能力,比如:img link iframe script。

​ JSONP 就是利用 script 标签的跨域能力来发送请求的,只支持get请求。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JSONP案例</title>
</head>
<body>
    用户名: <input type="text" id="username">
    <p></p>
    <script>
        //获取 input 元素
        const input = document.querySelector('input');
        const p = document.querySelector('p');
        
        //声明 handle 函数
        function handle(data){
            input.style.border = "solid 1px #f00";
            //修改 p 标签的提示文本
            p.innerHTML = data.msg;
        }

        //绑定事件
        input.onblur = function(){
            //获取用户的输入值
            let username = this.value;
            //向服务器端发送请求 检测用户名是否存在
            //1. 创建 script 标签
            const script = document.createElement('script');
            //2. 设置标签的 src 属性
            script.src = 'http://127.0.0.1:8000/check-username';
            //3. 将 script 插入到文档中
            document.body.appendChild(script);
        }
    </script>
</body>
</html>
//express服务代码
app.all('/check-name', (req, res) => {
  res.setHeader('Access-Control-Allow-Origin', '*');
  let data = { name: '张三', text: '用户名已存在!' }
  res.send(`handle(${JSON.stringify(data)})`)
})

8.jQuery发送JSONP请求

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>jQuery-jsonp</title>
    <style>
        #result{
            width:300px;
            height:100px;
            border:solid 1px #089;
        }
    </style>
    <script crossorigin="anonymous" src='https://cdn.bootcss.com/jquery/3.5.0/jquery.min.js'></script>
</head>
<body>
    <button>点击发送 jsonp 请求</button>
    <div id="result">

    </div>
    <script>
        $('button').eq(0).click(function(){
            $.getJSON('http://127.0.0.1:8000/jquery-jsonp-server?callback=?', function(data){
                $('#result').html(`
                    名称: ${data.name}<br>
                    地区: ${data.city}
                `)
            });
        });
    </script>
</body>
</html>
//express服务
app.all('/jquery-jsonp-server',(request, response) => {
  const data = {
      name:'张三',
      city: ['北京','上海','深圳']
  };
  //将数据转化为字符串
  let str = JSON.stringify(data);
  //接收 callback 参数
  let cb = request.query.callback;

  //返回结果
  response.end(`${cb}(${str})`);
});

9.cors

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

1) CORS 是什么?

​ Cross-Origin Resource Sharing),跨域资源共享。CORS 是官方的跨域解决方

案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持

get 和 post 请求。跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些

源站通过浏览器有权限访问哪些资源

2) CORS 怎么工作的?

​ CORS 是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应

以后就会对响应放行。

3) 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 返回的响应");

​ });

posted @ 2023-06-01 13:55  天官赐福·  阅读(9)  评论(0编辑  收藏  举报
返回顶端