AJAX学习笔记

第一章 原生AJAX

1.1ajax简介

  • 异步JS和XML
  • 在浏览器中向服务器发送异步请求,无需刷新网页获取数据
  • 提高网页加载速度,提高用户体验
  • 是一种将现有标准组合在一起的新方式

1.2XML介绍

  • 可扩展标记语言
  • XML被设计用来传输和存储数据,HTML用来呈现数据
  • XML全都是自定义标签,HTML都是预定义标签
  • ajax数据交换使用XML,前端JS对收到的XML格式字符串进行解析提取数据,现在被JSON取代

1.3ajax特点

1.3.1优点
  • 无需刷新页面就可与服务器端进行通信
  • 与需根据用户事件更新部分页面内容
1.3.2缺点
  • 无浏览历史,不能回退
  • 存在跨域问题(如默认不能在a.com向b.com发送ajax请求)
  • 对搜索引擎优化不友好,爬虫不能爬取ajax动态生成内容,只能爬取最开始HTTP响应体页面内容

1.4HTTP协议

  • hypertext transport protocol 超文本传输协议,规定了浏览器和万维网服务器之间互相通信的规则

  • 请求报文格式与参数

    请求行:请求类型如GET、POST等  URL路径  HTTP协议版本(1.1最多)
    请求头:Host: baidu.com
    	   Cookie: name=ddd
    	   Content-type: application/x-www-form-urlencoded
    	   User-Agent: chrome 83
    	   ...
    空行
    请求体:GET类型此处为空,POST这里可有内容  
    
  • 响应报文格式与参数

    响应行:协议类型 状态码 状态字符串
    响应头:Content-Type: text/html;charset=utf-8
    	   Content-length: 2048
    	   Content-encoding: gzip
    	   ...
    空行
    响应体:<html>
    	   </html>
    

1.5Node.js

  • ajax应用的服务端

1.6express框架

  • 基于Node.js平台的web开发框架

  • 基本使用案例:

    //1.引入express
    const express = require('express');
    
    //2.创建应用对象
    const app = express();
    
    //3.创建路由规则
    //request是对请求报文的封装
    //response是对响应报文的封装
    app.get('/', (request, response) => {
        //设置响应
        response.send('HELLO EXPRESS');
    });
    
    //4.监听端口启动服务.
    app.listen(8000, () => {
        console.log("服务已经启动,8000 端口监听中...")
    })
    

    命令node express基本使用.js运行

1.7ajax请求的基本操作(案例)

  • server后端

    app.get()内参数设置:

    请求路径

    • 召回函数(request,response)=>{}
      • 设置响应头允许跨域response.setHeader('Access-Control-Allow-Origin','*');
      • 设置响应体response.send('');
  • 前端script

    • 获取元素

    • 绑定事件

    • 编写事件处理程序

      • 创建xhr对象

        let xhr = new XMLHttpRequest()

      • 初始化,设置请求方法和url,设置url参数 :url?后跟参数如a=1,用&并列参数(适用于GET)

        xhr.open('GET','http://127.0.0.1:8000/server');

      • 发送请求 ,如果是POST,请求体在send里直接设置,加’',内直接写入,格式自由

        xhr.send();

      • 监听onreadystatechange事件,处理服务器返回的结果xhr.response,注意判断状态码

        xhr.onreadystatechange = function(){}

  • 设置请求参数:

    • GET类型,在xhr.open()函数中url后以?分隔,url?,后跟参数如a=1,用&并列参数
    • POST类型,在xhr.send()函数内写’参数’,格式可以是'a=10&b=6','a:100&b:20','123456'
  • 设置请求头

    • xhr.setRequestHeader('首部名字','首部值')
    • 可以自定义首部,需要服务端设置返回首部 response.setHeader('Access-Control-Allow-Headers','*');,为防止浏览器发送我们需要的请求前发送OPTIONS(无法获得响应),可以修改后端为app.all()可以接受任意请求
    • 一般会把身份校验相关信息放在头内,传递给服务器,服务器提取数据进行身份校验
  • 服务端响应JSON数据的处理

    • 服务端

      • 定义数据对象
      • 利用JSON.stringify(data)方法对数据进行字符串转换
    • 客户端/前端

      • 若手动对接收的字符串转换为对象,利用JSON.parse(xhr.response)方法

        app.all('/json-server', (request, response) => {
            //设置响应
            //设置响应头,设置允许跨域
            response.setHeader('Access-Control-Allow-Origin','*');
            response.setHeader('Access-Control-Allow-Headers','*');
            //响应一个数据
            let data ={
                name: 'ddd'
            }
            //对对象进行字符串转换
            let str = JSON.stringify(data);
            //设置响应体
            response.send(str);
        });
        
      • 若自动转换接收的字符串为对象,创建ajax对象后设置响应体数据类型xhr.responseType = 'json';,之后xhr.response就是一个对象

        <body>
        <!--在窗口内按下任意键盘按键则向服务端发送请求,服务端返回结果-->
            <div id="result"></div>
            <script>
                //绑定对象
                let r = document.getElementById('result');
                //绑定键盘按下事件
                window.onkeydown = function () {
                    // test
                    // console.log('test')
                    //创建ajax对象
                    let xhr = new XMLHttpRequest();
                    //设置响应体数据类型
                    xhr.responseType = 'json';
                    //初始化,设置请求类型和url
                    xhr.open('GET','http://127.0.0.1:8000/json-server');
                    //发送
                    xhr.send();
                    //监听处理
                    xhr.onreadystatechange = function () {
                        if(xhr.readyState===4){
                            if(xhr.status >=200&&xhr.status<300){
                                //响应体放在盒子中
                                //r.innerHTML=xhr.response;
                                //手动对数据进行转换,字符串转换为对象
                                // let data = JSON.parse(xhr.response);
                                // // console.log(data);
                                // r.innerHTML = data.name;
                                //自动转换,利用xhr的属性设置响应体数据类型
                                r.innerHTML = xhr.response.name;
                            }
                        }
                    }
                }
            </script>
        
        </body>
        

1.8ajax中IE缓存问题

  • 概述:IE浏览器会对ajax请求结果做缓存,导致后续若有相同请求,返回本地缓存,不是服务器的最新数据,如果时效性要求高则不适应

  • 解决:给请求添加时间戳xhr.open("GET",'http://127.0.0.1:8000/ie?t='+Date.now());

1.9ajax请求超时和网络异常处理

  • 超时设置xhr.timeout
  • 超时回调xhr.ontimeout = function () {}
  • 网络异常回调xhr.onerror = function () {}
let xhr = new XMLHttpRequest();
//超时设置 2s没有返回结果就会cancel
xhr.timeout = 2000;
//超时回调
xhr.ontimeout = function () {
    alert("网络异常,请稍后重试!!");
}
//网络异常回调
xhr.onerror = function () {
    alert("你的网络似乎除了一些问题!");
}
xhr.open("GET",'http://127.0.0.1:8000/delay');

1.10ajax取消请求

手动在结果还未返回时取消请求调用abort()

let btns = document.querySelectorAll('button');
        let x = null;
		//点击第一个按键发送
        btns[0].onclick = function () {
            x = new XMLHttpRequest();
            x.open("GET",'http://127.0.0.1:8000/delay');
            x.send();
        }
        //点击第二个按键abort
        btns[1].onclick = function () {
            x.abort();
        }

1.11ajax请求重复发送问题

客户端一直发送相同请求会使服务器压力过大,这时候可以考虑后续出现相同请求则取消前面没有完成的相同请求,这样就保证了始终只有一个请求。方法是利用标识变量

    //获取元素对象
    let btns = document.querySelectorAll('button');
    let x = null;
    //标识变量
    let isSending = false;//是否正在发送AJAX请求

    btns[0].onclick = function () {
        if(isSending)x.abort();// 如果正在发送,则取消该请求,创建一个新的请求
        x = new XMLHttpRequest();
        //修改标识变量的值
        isSending = true;
        x.open("GET",'http://127.0.0.1:8000/delay');
        x.send();
        x.onreadystatechange = function () {
            if(x.readyState === 4){
                //修改标识变量
                isSending = false;
            }
        }

    }

第二章 Axios发送AJAX请求

2.1 axios简介

一个ajax工具库,是Vue和React推荐的ajax请求工具包

2.2axios特点

  • 可以从浏览器发起ajax请求
  • 可以从node.js发起http请求
  • 支持Promise API
  • 可以拦截请求和响应
  • 可以转换请求和响应数据
  • 可以取消请求
  • 自动转换成JSON
  • 客户端支持防护XSRF攻击

2.3axios发送请求

  • GET

  • POST

  • AJAX

    <!DOCTYPE html>
    <html lang="zh-CN">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>axios 发送 ajax请求</title>
        <script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/1.5.0/axios.js"></script>
      <style></style>
    </head>
    
    <body>
    <button>GET</button>
    <button>POST</button>
    <button>AJAX</button>
    
    <script>
        const btns =document.querySelectorAll('button');
        //配置baseURL
        axios.defaults.baseURL='http://127.0.0.1:8000';
        btns[0].onclick = function () {
            //GET请求
          axios.get('/axios-server',{
            //url参数
            params:{
              id:100,
              vip:6
            },
            //请求头信息
            headers:{
              name:'ddd',
              age: 21
            }
    
          }).then(value => {
            console.log(value);
          })
        }
    
        btns[1].onclick = function () {
          axios.post('/axios-server',{
            //请求体
            username:'admin',
            password:'123'
          },{
            //url
            params: {
              vip:100,
              id:3
            },
            //请求头参数
            headers:{
              height:165,
              weight:95
            }
          })
        }
    
        btns[2].onclick = function(){
          axios({
            //请求方法
            method:'POST',
            //url
            url:'/axios-server',
            //url参数
            params:{
              id:10,
              level:40
            },
            //头信息
            headers:{
              a:100,
              b:200
            },
            //请求体参数
            data:{
              username:'admin',
              password:'123'
            }
          }).then(response =>{
            console.log(response);
            //响应状态码
            console.log(response.status);
            //响应状态字符串
            console.log(response.statusText);
            //响应头信息
            console.log(response.headers);
            //响应体
            console.log(response.data);
          })
        }
    </script>
    </body>
    
    
    </html>
    
  • fetch()函数也可以发送ajax请求

第三章 跨域

3.1同源策略

  • 浏览器的一种安全策略,ajax默认遵守

  • 同源:协议、域名、端口号完全相同

  • 当前网页url与其ajax请求目标资源的url需要协议、域名、端口号相同

  • 违背同源策略就是跨域

  • 跨域问题常有,因为单台服务器服务有上限,性能有瓶颈

3.2跨域的解决方法

3.2.1 JSONP
  • JSON with Paadding 非官方的跨域解决方案,只支持get请求
  • JSONP利用<script>标签的跨域能力发送请求(有的网页标签本身具有跨域能力,如:img link iframe script)
  • 原理:返回一个函数调用(返回JS代码,才能被解析),函数的参数就是客户端想收到的数据,让前端对此进行处理,函数需要前端提前声明
原生JSONP跨域实践

判断前端输入用户名是否存在

  • 前端

    <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:9000/check-username';
                //3.将script插入到文档中
                document.body.appendChild(script);
    
            }
        </script>
    
    </body>
    
  • server

    //检测用户名是否存在
    app.all('/check-username',(request,response)=>{
        //response.send(console.log('hello jsonp-server'));
        const data = {
            exist: 1,
            msg:'用户名已经存在'
        };
        //数据转化为字符串
        let str = JSON.stringify(data);
        //返回结果
        response.end(`handle(${str})`);
    })
    
3.2.2 CORS
  • Cross-Origin Resource Sharing 跨域资源共享 官方跨域解决方案

  • 特点:

    • 完全在服务端进行处理,不需要客户端操作
    • 支持get和post请求
    • 新增一组HTTP首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源
  • 工作原理:服务器设置一个响应头告诉浏览器,该请求允许跨域,浏览器收到该响应后就会对响应放行

  • CORS的使用:添加响应头即可

    //cors服务-server
    app.all('/cors-server',(request,response)=>{
        //设置跨域响应头
        response.setHeader("Access-Control-Allow-Origin","*");
        response.send('hello CORS');
    });
    
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值