Ajax学习笔记

本文深入解析Ajax如何解决传统网站问题,如无刷新更新数据、页面加载优化。涵盖GET/POST请求、数据转换、跨域处理、axios和fetch的使用,以及CORS原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Ajax 基础

传统网站中存在的问题

  1. 网速较慢的情况下,页面加载时间长,用户只能等待
  2. 表单提交后,如果一项内容不合格,需要重新填写所有表单内容
  3. 页面跳转,重新加载页面,造成资源浪费,增加用户等待时间

Ajax 概述

  1. 它是浏览器提供的一套方法,可以实现页面无刷新更新数据,提高用户浏览网站应用的体验

Ajax 的缺点

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

Ajax 的应用场景

  1. 页面上拉加载更多数据
  2. 列表数据无刷新分页
  3. 表单项离开焦点数据验证
  4. 搜索框提示文字下拉列表

注意

  1. 在终端服务器中打开
  2. npm init --yes 创建了package.json文件
  3. npm i express 安装express框架 多出了node_modules文件夹 以及 package-lock.json文件
  4. ctrl+c 可以释放端口

Ajax 运行原理及实现

GET

<body>
    <button>点击发送请求</button>
    <div id="result"></div>
    <script>
        const btn = document.querySelector('button');
        const result = document.querySelector('#result');
        btn.addEventListener('click', function() {
          // 1. 创建对象
            const xhr = new XMLHttpRequest();
          // 2. 初始化 设置请求方法和 url
          // 请求方法可以是GET和POST
            xhr.open('GET', 'http://localhost:8000/server?a=3&b=4');
          // 3. 发送
            xhr.send();
          // 4. 事件绑定 处理服务器返回的结果
          // on 当...的时候
          // readystate 是 xhr 对象中的属性,表示状态 0 1 2 3 4
          // 0 未开始  1 初始化  2 发送  3 输送了一部分数据  4 输送了全部数据 
          // change 改变
            xhr.onreadystatechange = function() {
              // 判断 (服务器端返回了所有结果)
                if (xhr.readyState === 4) {
                  // 判断响应码 
                  // 200-300 的响应码都表示成功
                    if (xhr.status >= 200 && xhr.status < 300) {
                      // 处理结果  行 头 空行 体
                      // 响应行
                        console.log(xhr.status);// 状态码
                        console.log((xhr.statusText));// 状态字符串
                        console.log(xhr.getAllResponseHeaders());// 所有响应头
                        console.log(xhr.response); // 响应体
                        result.innerHTML = xhr.response;// 设置result文本
                    }
                }
            }
        });
    </script>
</body>

设置url

  1. 路径与参数之间以问号(‘?’)分隔,参数以键值对形式存在,参数间以’&'分隔

POST 以及 自定义请求头

<body>
    <div id="result"></div>
    <script>
        const result = document.querySelector('#result');
        result.addEventListener('mouseover', function() {
            const xhr = new XMLHttpRequest();
            xhr.open('POST', 'http://localhost:8000/server');
            // 设置请求头 Content-Type 对应的是 参数=参数值&参数=参数值 这种格式
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            // 自定义请求头 想要自定义请求头,需要同时在后端设置app.all 和 响应头
            xhr.setRequestHeader('name','atguigu');
            xhr.send('a=1&b=2&c=3');
            xhr.onreadystatechange = function() {
                if (xhr.readyState === 4) {
                    if (xhr.status >= 200 && xhr.status < 300) {
                        result.innerHTML = xhr.response;
                    }
                }
            }
        });
    </script>
</body>

数据转换

server.js 文件中
// 这里创建了一个date对象,name 属性 以及其内容
const date = {
        name: 'atguigu'
    };
// 将date对象内容转换为字符串
    let str = JSON.stringify(date);
// response.send() 里面数据类型必须为字符串
    response.send(str);
html 文件中
// 1. 将全部响应内容转换回相应状态
xhr.responseType = 'json';
// 输出
result.innerHTML = xhr.response.name;

// 2. 手动转换内容
let date = JSON.parse(xhr.response);
result.innerHTML = date.name;

ie 缓存问题

xhr.open('GET','http://localhost:8000/server?t='+Date.now());
// 就是在路径后面加一个时间戳 t='Date.now()

超时设置 网络异常提醒

xhr.open('GET', 'http://localhost:8000/delay');
// xhr 的timeout 以及ontimeout 必须放在open 和send 之间
            xhr.timeout = 2000;// 超时时间,单位是毫秒
            xhr.ontimeout = function() {
                alert('网络异常,请稍后重试');// 超时处理
            }
            xhr.onerror = function() {
                alert('您的网络似乎出了一些问题');// 网络异常提醒
            }
            xhr.send();

取消发送

// xhr.abort(); 用于取消发送

// xhr.abort(); 的实际应用 可用于处理重复发送 把前面的取消掉保留最新的
<body>
    <button>发送请求</button>
    <script>
        const btns = document.querySelectorAll('button');
        // 标识变量
        let isSending = false;
        let xhr = null;
        btns[0].addEventListener('click', function() {
            // 判断标识变量
            if (isSending) xhr.abort();
            xhr = new XMLHttpRequest();
            // 修改标识变量的是
            isSending = true;
            xhr.open('GET', 'http://localhost:8000/delay');
            xhr.send();
            xhr.onreadystatechange = function() {
                if (xhr.readyState === 4) {
                    // 修改标识变量
                    isSending = false;
                }
            }
        });
    </script>
</body>

axios

  1. axios 是一个库,需要自己引入axios的链接
<body>
    <button>GET</button>
    <button>POST</button>
    <button>ANXIOS</button>
    <script>
        const btns = document.querySelectorAll('button');

        // 配置 baseURL
        axios.defaults.baseURL = 'http://localhost:8000';

        // 要注意逗号哦
        btns[0].addEventListener('click', function() {
            axios.get('/axios-server', {
                // url参数
                params: {
                    id: 100,
                    vip: 7
                },
                // 请求头信息
                headers: {
                    name: 'atguigu',
                    age: 20
                }
            }).then(value => {
                console.log((value));
            });
        });

        // axios.post(url[, data[, config]])
        // 第一个参数是url 第二个参数是请求体 第三个参数是其他配置
        btns[1].addEventListener('click', function() {
            axios.post('/axios-server', {
                username: 'admin',
                password: 'admin'
            }, {
                // url
                params: {
                    id: 200,
                    vip: 9
                },
                // 请求头参数
                headers: {
                    height: 180,
                    weight: 180,
                },
            })
        });

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

fetch 函数

<body>
    <button>发送ajax请求</button>
    <script>
        const btn = document.querySelector('button');
        btn.addEventListener('click', function() {
            fetch('http://localhost:8000/fetch-server', {
                // 请求方法
                method: 'POST',
                // 请求头
                headers: {
                    name: 'atguigu'
                },
                // 请求体
                body: 'a=3&b=4&c=5'
            }).then(response => {
                // return response.text(); 用于处理字符串结果
                return response.json(); // 用于处理josn结果
            }).then(response => {
                console.log(response); // 这样才可以打印出响应数据
            })
        });
    </script>
</body>

同源 跨域

同源策略

  1. 同源策略是浏览器的一种安全策略
  2. 同源:协议、域名、端口号 必须完全相同,即相同的来源,来自同一个服务器
  3. 违背同源策略就是跨域

跨域解决

JSONP
  1. JSONP 仅支持get 请求
  2. 网页中一些标签天生具有跨域能力,比如:img、link、iframe、script
  3. JSONP 利用script 标签的跨域能力来发送请求
  4. 期望返回的结果:函数的调用(js 代码),函数中的实参就是服务器想要给客户端返回的数据,该函数需要提前声明
app.all('/jsonp-server', (request, response) => {
    const data = {
        name: 'admin'
    };
    let str = JSON.stringify(data);
  // 这里用response.end() 来输出结果,我也不知道为什么,据说用send会有特殊的请求头
  // 无论send 还是 end 括号里面都得是字符串
  // 函数的调用传回到客户端了 函数的实参就是服务端想要给客户端传回的数据
    response.end(`handle(${str})`);
});
  1. script 标签的用法:
// 1. 创建 script 标签
const script = document.createElement('script');
// 2. 设置标签的src属性
script.src = 'http://localhost:8000/check-username';
// 3. 将 script 插入到文档中
document.body.appendChild(script);
字符串拼接
// 字符串中嵌入变量
let name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`

// `${}` 的用法为ES6新增,用反引号``来括住字符串,在其中引用变量则用${变量}
CORS
  1. CORS 跨域资源共享。
  2. CORS 不需要再客户端做任何特殊的操作,完全在服务器中进行处理
  3. CORS 支持get 和 post 请求
  4. 跨域资源共享新增了一组HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源
  5. CORS 通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后就会对响应放行

Access-Control-Allow-Origin

Access-Control-Allow-Origin: <origin> | *

origin 参数的值指定了允许访问该资源的外域 URI。对于不需要携带身份凭证的请求,服务器可以指定该字段的值为通配符,表示允许来自所有域的请求

Access-Control-Allow-Methods

Access-Control-Allow-Methods: <method>[, <method>]*

用于预检请求的响应。其指明了实际请求所允许使用的 HTTP 方法

Access-Control-Allow-Headers

Access-Control-Allow-Headers: <field-name>[, <field-name>]*

用于预检请求的响应。其指明了实际请求中允许携带的首部字段

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值