AJAX知识点整理

目录

一、原生AJAX

1.1 AJAX简介

1.2 XML简介

1.3 AJAX的特点

1.3.1 AJAX的优点

1.3.2 AJAX的缺点

1.4 安装node.js

1.5 安装express

二、HTTP协议请求报文与响应文本结构

2.1 请求报文

2.2 响应报文

2.2.1 案例练习 - AJAX - GET请求的基本操作

2.2.2 案例练习 - AJAX - POST设置请求体

2.2.3 案例练习 - AJAX - 服务端响应JSON数据

三、nodemon安装

四、原生AJAX的基本使用

4.1 IE缓存问题

4.2 请求超时与网络异常处理

4.3 取消请求

4.4 AJAX请求重复发送问题

五、JQuery中的AJAX

5.1 get请求

5.2 post请求 

5.3 通用方法

六、Axios发送AJAX请求

6.1 axios - get请求

6.2 axios - post请求

6.3 axios函数发送请求

七、fetch函数发送AJAX请求

 八、跨域

8.1 同源策略

8.1.1 同源策略案例练习

8.2 如何解决跨域

8.2.1 JSONP

8.2.2 jQuery发送jsonp请求

8.3 CORS


一、原生AJAX

1.1 AJAX简介

AJAX,即异步的JS和XML。通过AJAX可以在浏览器中向服务器发送异步请求,最大优势:无刷新获取数据。AJAX是一中将现有的标准组合在一起使用的新方式

在网页中的应用:

  1. 搜索栏中输入后有相关关键词提醒
  2. 注册或者登录界面下,输入框输入内容后可能出现的下方文字提醒
  3. 鼠标移动到某一区域,弹出 上/下方 功能模块
  4. 移动到菜单栏,弹出二级或者三级的菜单栏

1.2 XML简介

XML 可扩展标记语言

XML 被设计用来传输和存储数据

XML和HTML类似,不同的是HTML中都是预定义标签,而XML中没有预定义标签,全是自定义标签,用来表示一些数据

1.3 AJAX的特点

1.3.1 AJAX的优点

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

1.3.2 AJAX的缺点

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

1.4 安装node.js

Node.js 中文网Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。Node.js 的包管理器 npm,是全球最大的开源库生态系统。http://nodejs.cn/

1.5 安装express

1.终端初始化环境

npm init --yes

 2. 下载express包

npm install express --save

3. 代码编写

// 1. 引入express
const express = require('express');

// 2. 创建应用对象
const app = express();

// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
app.get('/', (request,response)=>{
    // 设置响应
    response.send('HELLP EXPRESS');
});

// 4. 监听端口启动服务
app.listen(8000, ()=>{ 
    console.log('服务已经其中,8000端口监听中');
});

4. 终端运行

node express基本使用.js 

二、HTTP协议请求报文与响应文本结构

2.1 请求报文

行        GET / POST  /s?ie=utf-8   HTTP/1.1

头        Host:

           Cookie:

           Content-type:

           User-Agent:

空行

体        例如:username:admin&password=admin        

(行 为GET,请求体为空;行 为POST,请求体可以不为空)

2.2 响应报文

行        HTTP/1.1  200  OK

头         Content-Type: text/html;charst=utf-8

             Content-length: 2048

             Content-encoding: gzip

空行

体           <html>

                       <head>

                                <body>

                                        ....

                                </body> 

                       </head>

               </html>

2.2.1 案例练习 - AJAX - GET请求的基本操作

案例前操作,需先安装nodeJS

server.js

// 1. 引入express
const express = require('express');

// 2. 创建应用对象
const app = express();

// 3. 创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
app.get('/server', (request,response)=>{
    // 设置响应头 设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');

    // 设置响应体
    response.send('HELLO AJAX');
    
});

// 4. 监听端口启动服务
app.listen(8000, ()=>{ 
    console.log('服务已经启动, 8000端口监听中');
});

1-GET.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>AJAX GET 请求</title>
    <style>
        #result{
            width: 200px;
            height: 100px;
            border: 1px solid red;
        }
    </style>
</head>
<body>
    <button>点击发送请求</button>
    <div id="result"></div>
    <script>
        // 获取button元素  [0]指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');
            // 3. 发送
            xhr.send();
            // 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);// 响应体

                        result.innerHTML = xhr.response;
                    } else {

                    }
                }
            }
        }
    </script>
</body>
</html>

2.2.2 案例练习 - AJAX - POST设置请求体

server.js 添加新的代码段,并重启服务

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

    // 设置响应体
    response.send('HELLO AJAX POST');
    
});

2-POST.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>AJAX POST请求</title>
    <style>
        #result{
            width: 300px;
            height: 300px;
            border: 1px solid skyblue;
        }
    </style>
</head>
<body>
    <div id="result"></div>
    <script>
        const result = document.getElementById('result');
        result.addEventListener('mouseover', function(){
            const xhr = new XMLHttpRequest();
            xhr.open('post','http://127.0.0.1:8000/server');
            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>
</html>

 鼠标移动入框内

 请求体

2.2.3 案例练习 - AJAX - 服务端响应JSON数据

server.js 添加新的代码段,并重启服务

app.all('/json-server', (request,response)=>{
    // 设置响应头 设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    // 设置响应头
    response.setHeader('Access-Control-Allow-Headers','*');
    // 响应一个数据
    const data = {
        name: '9527'
    }
    let str = JSON.stringify(data);
    response.send(data);

    
});

3-JSON.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>JSON响应</title>
    <style>
        #result{
            width: 200px;
            height: 200px;
            border: 1px solid skyblue;
        }
    </style>
</head>
<body>
    <div id="result"></div>
    <script>
        const result = document.getElementById('result');
        window.onkeydown = function(){
            const xhr = new XMLHttpRequest();
            // 自动转化数据
            xhr.responseType = 'json';
            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){
                        // 手动转化数据为JSON
                        // let data = JSON.parse(xhr.response);
                        console.log(xhr.response);
                        result.innerHTML = xhr.response.name;
                    }
                }
            }
        }
    </script>
</body>
</html>

 点击键盘后

三、nodemon安装

前提条件:已经安装nodeJS

nodemon可以使在修改服务器端文件后,会自动检测重启服务,省略手动重启步骤

nodemon - npm (npmjs.com)https://www.npmjs.com/package/nodemon

终端内输入

npm install -g nodemon

启动服务

nodemon [your node app]

 如果出现禁止允许脚本问题,在nodemon前加npx

npx nodemon [your node app]

 

四、原生AJAX的基本使用

4.1 IE缓存问题

server.js 添加新的代码段

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

    // 设置响应体
    response.send('HELLO IE');
    
});

4-IE.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>IE缓存问题</title>
    <style>
        #result{
            width: 200px;
            height: 200px;
            border: 1px solid skyblue;
        }
    </style>
</head>
<body>
    <button>点击发送请求</button>
    <div id="result"></div>
    <script>
        const btn = document.getElementsByTagName('button')[0];
        const result = document.querySelector('#result');
        btn.addEventListener('click',function(){
            const xhr = new XMLHttpRequest();
            // ?t='+Date.now()解决ie缓存问题
            xhr.open('GET','http://127.0.0.1:8000/ie?t='+Date.now());
            xhr.send();
            xhr.onreadystatechange = function(){
                if(xhr.readyState === 4){
                    if(xhr.status >=200 && xhr.status < 300){
                        result.innerHTML = xhr.response;
                    }
                }
            }
        });
    </script>
</body>
</html>

4.2 请求超时与网络异常处理

server.js 添加新的代码段

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

    setTimeout(() => {
        response.send('延时响应');
    },3000)
});

5-超时与网络异常.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>请求超时与异常问题处理</title>
    <style>
        #result{
            width: 200px;
            height: 200px;
            border: 1px solid skyblue;
        }
    </style>
</head>
<body>
    <button>点击发送请求</button>
    <div id="result"></div>
    <script>
        const btn = document.getElementsByTagName('button')[0];
        const result = document.querySelector('#result');
        btn.addEventListener('click',function(){
            const xhr = new XMLHttpRequest();
            // 超时设置
            xhr.timeout = 2000;
            // 超时回调
            xhr.ontimeout = function(){
                alert('网络异常,请稍后重试!')
            }
            // 网络异常回调
            xhr.onerror = function(){
                alert('你的网络似乎出了一些问题!');
            }
            xhr.open('GET','http://127.0.0.1:8000/delay');
            xhr.send();
            xhr.onreadystatechange = function(){
                if(xhr.readyState === 4){
                    if(xhr.status >=200 && xhr.status < 300){
                        result.innerHTML = xhr.response;
                    }
                }
            }
        });
    </script>
</body>
</html>

4.3 取消请求

<!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>取消请求</title>
</head>
<body>
    <button>点击发送</button>
    <button>点击取消</button>
    <script>
        const 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();
        }

        btns[1].onclick = function(){
            x.abort();
        }
        
    </script>
</body>
</html>

4.4 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>重复请求问题</title>
</head>
<body>
    <button>点击发送</button>
    <button>点击取消</button>
    <script>
        const btns = document.querySelectorAll('button');
        let x = null;
        // 添加标识变量
        let isSending = false;
        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;
                }
            }
        }

        btns[1].onclick = function(){
            x.abort();
        }
        
    </script>
</body>
</html>

五、JQuery中的AJAX

server.js

app.all('/jquery-server',(request,response) =>{
    response.setHeader('Access-Control-Allow-Origin','*');
    response.send('Hello JQuery AJAX');
});

5.1 get请求

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

  • url:请求的URL 地址
  • data:请求携带的参数
  • callback:载入成功时回调函数
  • type:设置返回内容格式,xml, html, script, json, text, _default
        $('button').eq(0).click(function(){
            $.get('http:127.0.0.1:8000/jquery-server',{a:1,b:2},function(data){
                console.log(data);
            })
        });

5.2 post请求 

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

  • url:请求的URL 地址
  • data:请求携带的参数
  • callback:载入成功时回调函数
  • type:设置返回内容格式,xml, html, script, json, text, _default
        $('button').eq(1).click(function(){
            $.post('http:127.0.0.1:8000/jquery-server',{a:1,b:2},function(data){
                console.log(data);
            })
        });

5.3 通用方法

app.all('/jquery-server',(request,response) =>{
    response.setHeader('Access-Control-Allow-Origin','*');
    // response.send('Hello JQuery AJAX');
    let data = {name:'9527'};
    response.send(JSON.stringify(data));
});
        $('button').eq(2).click(function(){
            $.ajax({
                // url
                url: 'http://127.0.0.1:8000/jquery-server',
                // 参数
                data: {a:1, b:2},
                // 请求类型
                type: 'GET',
                // 响应体结果
                dataType: 'json',
                //成功回调
                success: function(data){
                    console.log(data);
                },
                // 超时事件
                timeout: 2000,
                // 失败回调
                error:function(){
                    console.log('出错!');
                }
            });
        });

六、Axios发送AJAX请求

GitHub - axios/axios: Promise based HTTP client for the browser and node.jshttps://github.com/axios/axiosaxios (v0.26.1) - Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 Node.js 中。 | BootCDN - Bootstrap 中文网开源项目免费 CDN 加速服务https://www.bootcdn.cn/axios/

<script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/0.26.1/axios.min.js"></script>

server.js

app.all('/asiox-server',(request,response) =>{
    response.setHeader('Access-Control-Allow-Origin','*');
    response.setHeader('Access-Control-Allow-Headers','*');
    let data = {name:'9527'};
    response.send(JSON.stringify(data));
});

6.1 axios - get请求

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: 10001,
                    vip: 7
                },
                // 请求头信息
                headers: {
                    name: 'zhang3',
                    age: 24
                }
            }).then(value => {
                console.log(value);
            });
        }

6.2 axios - post请求

        btns[1].onclick = function(){
            axios.post('/axios-server',
            {
                username: 'admin',
                password: 'admin123'
            },
            {
                params: {
                    id: 1002,
                    vip: 2
                },
                headers: {
                    height: 180,
                    weight: 70
                }
            })
        }

6.3 axios函数发送请求

        btns[2].onclick = function(){
            axios({
                // 请求方法
                method: 'POST',
                // url
                url: '/axios-server',
                // url参数
                params: {
                    id: 1003,
                    vip: 10
                },
                // 头信息
                headers: {
                    a:1,
                    b:2
                },
                // 请求体参数
                data: {
                    username: 'admin',
                    password: 'admin123'
                }
            }).then(response=>{
                // 响应状态码
                console.log(response.status);
                // 响应状态字符串
                console.log(response.statusText);
                // 响应头信息
                console.log(response.headers);
                // 响应体
                console.log(response.data);
            })
        }

七、fetch函数发送AJAX请求

WorkerOrGlobalScope.fetch() - Web API 接口参考 | MDN (mozilla.org)https://developer.mozilla.org/zh-CN/docs/Web/API/fetch语法

Promise<Response> fetch(input[, init]);

server.js 添加代码段 

app.all('/fetch-server',(request,response) =>{
    response.setHeader('Access-Control-Allow-Origin','*');
    response.setHeader('Access-Control-Allow-Headers','*');
    let data = {name:'9527'};
    response.send(JSON.stringify(data));
});

 fetch.html

    <button>AJAX请求</button>
    <script>
        const btn = document.querySelector('button');
        btn.onclick = function(){
            fetch('http://127.0.0.1:8000/fetch-server',{
                // 请求方法
                method:'POST',
                // 请求头
                headers:{
                    name: 'zhang3'
                },
                body: 'username=admin&password=admin123'
            }).then(response => {
                return response.json();
            }).then(response => {
                console.log(response);
            })
        }
    </script>

 八、跨域

8.1 同源策略

  • 同源策略(Same-Origin Policy)最早由Netscape 公司提出,是浏览器的一种安全策略
  • 同源: 协议、域名、端口号必须完全相同
  • 跨域: 违背同源策略就是跨域

违背同源策略就是跨域

8.1.1 同源策略案例练习

server.js

const express = require('express');

const app = express();

app.get('/home',(request,response)=>{
    response.sendFile(__dirname+'/index.html');
});

app.get('/data',(request,response)=>{
    response.send('用户数据');
})

app.listen(9000,()=>{
    console.log('服务已经启动...');
});

index.html

    <h1>同源策略测试案例</h1>
    <button>点击获取数据</button>
    <script>
        const btn = document.querySelector('button');
        btn.onclick = function(){
            const xhr = new XMLHttpRequest();
            xhr.open('GET','/data');
            xhr.send();
            xhr.onreadystatechange = function(){
                if(xhr.readyState === 4){
                    if(xhr.status >=200 && xhr.status < 300){
                        console.log(xhr.response);
                    }
                }
            }
        }
    </script>

8.2 如何解决跨域

8.2.1 JSONP

1. JSONP是什么

        JSONP(JSON with Padding),是一个非官方的跨域解决方案,只支持get请求

2. JSONP怎么工作的

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

        JSONP就是利用script标签的跨域能力来发送请求的

3. JSONP的使用

        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插入到文档中

document.body.appendChild(script);

        4)原生JSONP实践 - 案例练习

server.js添加代码段

app.all('/check-username',(request,response) => {
    const data = {
        exist:1,
        msg:'用户名已经存在'
    }
    let str = JSON.stringify(data);
    response.end(`handle(${str})`);
});

jsonp.html

    用户名: <input type="text" id="username">
    <p></p>
    <script>
        const input = document.querySelector('input');
        const p = document.querySelector('p');

        function handle(data){
            input.style.border = '1px solid red';
            p.innerHTML = data.msg;
        }
        input.onblur = function(){
            // 获取用户输入值
            let username = this.value;
            // 向服务器端发送请求,检测用户名是否存在
            // 创建script标签
            const script = document.createElement('script');
            // 设置标签的src属性
            script.src = 'http://127.0.0.1:8000/check-username';
            document.body.appendChild(script);
        }
    </script>

8.2.2 jQuery发送jsonp请求

server.js添加代码段

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})`);
});

jquery-jsonp.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>jQuery发送jspon请求</title>
    <style>
        #result{
            width: 300px;
            height: 300px;
            border: 1px solid skyblue;
        }
    </style>
    <script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.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>

8.3 CORS

跨源资源共享(CORS) - HTTP | MDN跨源资源共享 (CORS)(或通俗地译为跨域资源共享)是一种基于 HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其它origin(域,协议和端口),这样浏览器可以访问加载这些资源。跨源资源共享还通过一种机制来检查服务器是否会允许要发送的真实请求,该机制通过浏览器发起一个到服务器托管的跨源资源的"预检"请求。在预检中,浏览器发送的头中标示有HTTP方法和真实请求中会用到的头。https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

1. CORS 是什么?

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

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

3. CORS的使用

        主要是服务器端的设置:

app.all("/cors-server" , function (request , response) {
	//通过response 来设置响应头,来允许跨域请求
	response.set("Access-Control-Allow-Origin","*");
    response.set("Access-Control-Allow-Headers","*");
    response.set("Access-Control-Allow-Method","*");
	response.send("hello CORS");
});

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JHY97

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值