ajax学习笔记

 Ajax初步大致写法

1.onreadystatechange 事件

当请求被发送到服务器时,我们需要执行一些基于响应的任务。每当 readyState 改变时,就会触发 onreadystatechange 事件

        readyState(状态值):存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。

       //xhr内部有5种状态,值分别为:0、1、2、3、4(了解即可)

               xhr实例对象,在实例出来的那一刻状态就是0

               xhr内部有5种状态,值分别为:0、1、2、3、4

                            0:实例出来的那一刻状态就是0,初始状态。

                            1:open已经调用了,但是send还没有调用,此时可以修改请求头内容。

                            2:send已经调用了,已经无法修改请求头

                            3:已经回来一部分数据了,小的数据会在此阶段一次性接收完毕,较大的数据有待进一步接收,响应头回来了。

                            4:数据全部接收完

        status(状态码):响应的HTTP状态码。

        //status,是指无论AJAX访问是否成功,由HTTP协议根据所提交的信息,服务器所返回的HTTP头信息代码。

       HTTP状态码总共可分为5大类  :

      1xx:信息响应类,表示接收到请求并且继续处理(例如;100客户必须继续发送请求)
      2xx:处理成功响应类,表示动作被成功接收、理解和接受(例如;200交易成功)
      3xx:重定向响应类,为了完成指定的动作,必须接受进一步处理(例如;300请求的资源可在多处得到)
      4xx:客户端错误,客户请求包含语法错误或者是不能正确执行(例如;404指所请求的页面不存在、已被删除或无法访问)
     5xx:服务端错误,服务器不能正确执行一个正确的请求(例如;500服务器内部产生错误)

总体理解:可以简单的理解为state代表一个整体的状态。而status是这个大的state下面具体的小的状态。

2.为什么onreadystatechange的函数实现要同时判断readyState和status呢?

只使用readyState

由于只使用readystate做判断,它不理会放回的结果是200、404还是500,只要响应成功返回了,就执行接下来的javascript代码,结果将造成各种不可预料的错误。所以只使用readyState判断是行不通的。

只使用status判断

事实上,结果却不像预期那样。响应码确实是返回了200,但是总共弹出了3次窗口!第一次是“readyState=2”的窗口,第二次是“readyState=3”的窗口,第三次是“readyState=4”的窗口。由此,可见onreadystatechange函数的执行不是只在readyState变为4的时候触发的,而是readyState(2、3、4)的每次变化都会触发,所以就出现了前面说的那种情况。可见,单独使用status判断也是行不通的。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>1_ajax小试牛刀</title>
		<style>
			#content{
				width: 300px;
				height: 100px;
				border: 1px solid black;
				margin-top: 10px;
			}
		</style>
	</head>
	<body>
		<h3>该页面是测试:ajax小试牛刀</h3>
		<button id="btn">点我发送请求(原生js-ajax-get)</button>
		<div id="content"></div>
		<script type="text/javascript" >
			//获取按钮
			const btn = document.getElementById('btn')
			const content = document.getElementById('content')
			//给按钮绑定监听
			btn.onclick = ()=>{
				//1.创建xhr实例对象
				const xhr = new XMLHttpRequest()

				//on  当xxx时候
				//ready 准备
				//state 状态
				//change 状态
				//xhr内部有5种状态,值分别为:0、1、2、3、4
				//xhr实例对象,在实例出来的那一刻状态就是0
				xhr.onreadystatechange = ()=>{
					if(xhr.readyState === 4){
                         if (xhr.status >= 200 && xhr.status < 300) {
                        console.log(xhr.response);
                        content.innerHTML = `<h3>${xhr.response}</h3>`
                    }
					}
				}

				//2.指定发送请求的:method、url
				xhr.open('GET','http://127.0.0.1:8080/test_get')
				
				//3.发送请求
				xhr.send()
			}
		</script>
	</body>
</html>

1.ajax中get请求(只能携带2种参数query和params)

          1.形如:key=value&key=value 就是query参数的urlencoded编码形式

          2.形如:/xx/xxx/老刘/18 就是params参数

<<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <title>3_ajax_get请求</title>
    <style>
        #content {
            width: 300px;
            height: 100px;
            border: 1px solid black;
            margin-top: 10px;
        }
    </style>
</head>

<body>
    <h3>该页面是测试:ajax_get请求</h3>
    <button id="btn">点我发送请求(原生js-ajax-get)</button>
    <div id="content"></div>
    <script type="text/javascript">
        //获取按钮
        const btn = document.getElementById('btn')
        const content = document.getElementById('content')
            //给按钮绑定监听
        btn.onclick = () => {
            //1.创建xhr实例对象
            const xhr = new XMLHttpRequest()

            //绑定监听
            xhr.onreadystatechange = () => {
                if (xhr.readyState === 4) {
                    if (xhr.status >= 200 && xhr.status < 300) {
                        console.log(xhr.response);
                        content.innerHTML = `<h3>${xhr.response}</h3>`
                    }
                }
            }

            //#region 
            /* 
            		1.形如:key=value&key=value 就是query参数的urlencoded编码形式
            		2.形如:/xx/xxx/老刘/18 就是params参数
            */
            //#endregion
            //2.指定发送请求的:method、url、参数
            // xhr.open('GET','http://127.0.0.1:8080/test_get?name=老刘&age=18') //携带query参数
            xhr.open('PUT', 'http://127.0.0.1:8080/test_put') //携带params参数

            //3.发送请求
            xhr.send()
        }
    </script>
</body>

</html>

2. ajax中post请求【携带3种参数query,params和请求体(urlencoded,json)】

请求体比较常用:

         1.若追加响应头用于标识携带请求体参数的编码形式--urlencoded

             xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded')

            则

             xhr.send('name=老刘&age=18') //携带urlencoded编码形式的请求体参数

        2.若追加响应头用于标识携带请求体参数的编码形式--json

                xhr.setRequestHeader('Content-type','application/json')

             则

                const person = {name:'老刘',age:20}

                xhr.send(JSON.stringify(person)) //携带json编码形式的请求体参数

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>4_ajax_post请求</title>
		<style>
			#content{
				width: 300px;
				height: 100px;
				border: 1px solid black;
				margin-top: 10px;
			}
		</style>
	</head>
	<body>
		<h3>该页面是测试:ajax_post请求</h3>
		<button id="btn">点我发送请求(原生js-ajax-post)</button>
		<div id="content"></div>
		<script type="text/javascript" >
			//获取按钮
			const btn = document.getElementById('btn')
			const content = document.getElementById('content')
			//给按钮绑定监听
			btn.onclick = ()=>{
				//1.创建xhr实例对象
				const xhr = new XMLHttpRequest()

				//绑定监听
				xhr.onreadystatechange = ()=>{
					if(xhr.readyState === 4 ){
						if(xhr.status >= 200 && xhr.status < 300){
							console.log(xhr.response);
							content.innerHTML = `<h3>${xhr.response}</h3>`
						}
					}
				}

				//2.指定发送请求的:method、url、参数
				xhr.open('POST','http://127.0.0.1:8080/test_post')

				//追加响应头用于标识携带请求体参数的编码形式--urlencoded
				xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded')

				//追加响应头用于标识携带请求体参数的编码形式--json
				//xhr.setRequestHeader('Content-type','application/json')
				
				//3.发送请求
				const person = {name:'老刘',age:20}

				xhr.send('name=老刘&age=18') //携带urlencoded编码形式的请求体参数
				// xhr.send(JSON.stringify(person)) //携带json编码形式的请求体参数
			}
		</script>
	</body>
</html>

3.解析json数据

        responseType用于指定返回数据的格式

        如果服务器传输的数据是其他类型(不为指定的返回类型),输出为null

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>5_ajax_解析json数据</title>
		<style>
			#content{
				width: 300px;
				height: 100px;
				border: 1px solid black;
				margin-top: 10px;
			}
		</style>
	</head>
	<body>
		<h3>该页面是测试:ajax_解析json数据</h3>
		<button id="btn">点我发送请求(原生js-ajax-get)</button>
		<div id="content"></div>
		<script type="text/javascript" >
			const btn = document.getElementById('btn')
			const content = document.getElementById('content')

			btn.onclick = ()=>{
				//实例xhr
				const xhr = new XMLHttpRequest()

				//绑定监听
				xhr.onreadystatechange = ()=>{
					if(xhr.readyState === 4){
						if(xhr.status >= 200 && xhr.status <300){
							const {name,age,sex} = xhr.response//解构赋值
							content.innerHTML = (`
								<ul>
									<li>姓名:${name}</li>
									<li>年龄:${age}</li>
									<li>性别:${sex}</li>
								<ul>
								`)
						}
					}
				}
				
				//配置请求
				xhr.open('GET','http://127.0.0.1:8080/get_person')

				//responseType用于指定返回数据的格式
				xhr.responseType = 'json'

				//发送请求
				xhr.send()
			}
		</script>
	</body>
</html>

4.连续解构赋值复习(打印c的值)

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <title>Document</title>
</head>

<body>
    <script type="text/javascript">
        let obj = {a: 1,b: {c: 2}}
        // const {c} = obj.b //标准的解构赋值
        const {b: {c}} = obj //连续解构赋值
        console.log(c) //2
        const {b: {c: value}} = obj //连续解构赋值+重命名
        console.log(value) //2
    </script>
</body>

</html>

5.ajax使用步骤

 ajax请求状态

 6.Ajax请求异常和超时处理

        1.配置出错的回调

        xhr.onerror = ()=>{
                    alert('当前网络不稳定,请稍后重试');
                }

        2.超时时间(等2秒数据回不来不要了)

                xhr.timeout = 2000

        3.超时的回调

                xhr.ontimeout = ()=>{

                    alert('网速不给力,请切换网络重试');

                }

        

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>7_ajax请求的异常与超时处理</title>
		<style>
			#content{
				width: 300px;
				height: 100px;
				border: 1px solid black;
				margin-top: 10px;
			}
		</style>
	</head>
	<body>
		<h3>该页面是测试:ajax请求的异常与超时处理</h3>
		<button id="btn">点我发送请求(原生js-ajax-get)</button>
		<div id="content"></div>
		<script type="text/javascript" >
			const btn = document.getElementById('btn')
			const content = document.getElementById('content')

			btn.onclick = function(){
				//实例xhr
				const xhr = new XMLHttpRequest()

				//绑定监听
				xhr.onreadystatechange = function(){
					if(xhr.readyState === 4){
						if(xhr.status >= 200 && xhr.status <300){
							const {name,age,sex} = xhr.response
							content.innerHTML = (`
								<ul>
									<li>姓名:${name}</li>
									<li>年龄:${age}</li>
									<li>性别:${sex}</li>
								<ul>
								`)
						}
					}
				}
				
				//配置请求
				xhr.open('GET','http://127.0.0.1:8080/get_person_delay')

				//responseType用于指定返回数据的格式
				xhr.responseType = 'json'

				//配置出错的回调
				xhr.onerror = ()=>{
					alert('当前网络不稳定,请稍后重试');
				}

				//超时时间
				xhr.timeout = 2000 

				//超时的回调
				xhr.ontimeout = ()=>{
					alert('网速不给力,请切换网络重试');
				}

				//发送请求
				xhr.send()
			}
		</script>
	</body>
</html>

8.Ajax取消(关闭)请求

        xhr.abort()

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>8_ajax取消请求</title>
		<style>
			#content{
				width: 300px;
				height: 100px;
				border: 1px solid black;
				margin-top: 10px;
			}
		</style>
	</head>
	<body>
		<h3>该页面是测试:ajax取消请求</h3>
		<button id="btn">点我发送请求(原生js-ajax-get)</button>
		<button id="btn2">取消请求</button>
		<div id="content"></div>
		<script type="text/javascript" >
			const btn = document.getElementById('btn')
			const btn2 = document.getElementById('btn2')
			const content = document.getElementById('content')
			let xhr 

			btn.onclick = ()=>{
				//实例xhr
				xhr = new XMLHttpRequest()

				//绑定监听
				xhr.onreadystatechange = function(){
					if(xhr.readyState === 4){
						if(xhr.status >= 200 && xhr.status <300){
							const {name,age,sex} = xhr.response
							content.innerHTML = (`
								<ul>
									<li>姓名:${name}</li>
									<li>年龄:${age}</li>
									<li>性别:${sex}</li>
								<ul>
								`)
						}
					}
				}
				
				//配置请求
				xhr.open('GET','http://127.0.0.1:8080/get_person_delay')

				//responseType用于指定返回数据的格式
				xhr.responseType = 'json'

				//配置出错的回调
				xhr.onerror = ()=>{
					alert('当前网络不稳定,请稍后重试');
				}

				//超时时间
				xhr.timeout = 2000 

				//超时的回调
				xhr.ontimeout = ()=>{
					alert('网速不给力,请切换网络重试');
				}

				//发送请求
				xhr.send()
			}
			
			btn2.onclick = ()=>{
				xhr.abort()
			}
		</script>
	</body>
</html>

 9.Ajax避免多次请求(网络不好时,用户多次点击)

        外部定义一个变量isLoading ,点击事件用if一个判断是否为以展示去取消abort(),监听事件中改为false,发送请求后改为true

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>9_避免多次重复请求</title>
		<style>
			#content{
				width: 300px;
				height: 100px;
				border: 1px solid black;
				margin-top: 10px;
			}
		</style>
	</head>
	<body>
		<h3>该页面是测试:避免多次重复请求</h3>
		<button id="btn">点我发送请求(原生js-ajax-get)</button>
		<div id="content"></div>
		<script type="text/javascript" >
			const btn = document.getElementById('btn')
			const content = document.getElementById('content')
			let xhr 
			let isLoading

			btn.onclick = ()=>{
				if(isLoading) xhr.abort()
				
				//实例xhr
				xhr = new XMLHttpRequest()

				//绑定监听
				xhr.onreadystatechange = function(){
					if(xhr.readyState === 4){
						if(xhr.status >= 200 && xhr.status <300){
							isLoading = false
							const {name,age,sex} = xhr.response
							content.innerHTML = (`
								<ul>
									<li>姓名:${name}</li>
									<li>年龄:${age}</li>
									<li>性别:${sex}</li>
								<ul>
								`)
						}
					}
				}
				
				//配置请求
				xhr.open('GET','http://127.0.0.1:8080/get_person_delay')

				//responseType用于指定返回数据的格式
				xhr.responseType = 'json'

				//发送请求
				xhr.send()
				isLoading = true
			}
			
		</script>
	</body>
</html>

 10.jquery封装的ajax

        语法:$.ajax({ 本次发送 ajax 的配置项 })

        配置项:

        1.url:必填,表示请求地址

        2.method:选填,默认是 GET ,表示请求方式

        3.data:选填,默认是 ’ ’ ,表示携带给后端的参数

        5.dataType:选填,默认自动识别,表示后端返回给你的数据类型

        6.async:选填,默认是 true,表示是否异步

        7.success:选填,表示请求成功的回调函数(可以传3个参数,第一个结果result,第二 个是responsetext表示成功还是失败,第三个是xhr)

        8.error:选填,表示请求失败的回调函数
 精简版没有失败回调

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>10_jQuery封装的ajax</title>
		<style>
			#content{
				width: 300px;
				height: 100px;
				border: 1px solid black;
				margin-top: 10px;
			}
		</style>
		<script type="text/javascript" src="./js/jquery.min.js"></script>
	</head>
	<body>
		<h3>该页面是测试:jQuery封装的ajax</h3>
		<button id="btn1">点我发送请求(jQuery-ajax-get)</button>
		<button id="btn2">点我发送请求(jQuery-ajax-post)</button>
		<div id="content"></div>
		<script type="text/javascript" >
			const btn1 = $('#btn1')
			const btn2 = $('#btn2')
			const content = $('#content')

			btn1.click(()=>{
				//使用jQuery发送ajax-get(完整版)
				$.ajax({
					url:'http://127.0.0.1:8080/test_jquery_get', //请求地址
					method:'GET',//请求方式(默认值是GET)
					data:{school:'atguigu'},//携带的数据
					dataType:'json',//配置响应数据格式
					timeout:2000,//指定超时的时间
					success:(result,reponseText,xhr)=>{
						console.log(result,reponseText,xhr);
						content.append(`<div>汽车名:${result.name},价格:${result.price}</div>`)
					},//成功的回调
					error:(xhr)=>{console.log('请求出错了',xhr);} //失败的回调
				})

				//使用jQuery发送ajax-get(精简版)
				/* $.get('http://127.0.0.1:8080/test_jquery_get',{school:'atguigu'},(data)=>{
					console.log(data);
					content.append(`<div>汽车名:${data.name},价格:${data.price}</div>`)
				},'json') */
			})

			btn2.click(()=>{
				//使用jQuery发送ajax-post(完整版)
				$.ajax({
					url:'http://127.0.0.1:8080/test_jquery_post', //请求地址
					method:'POST',//请求方式(默认值是GET)
					data:{school:'atguigu'},//携带的数据
					dataType:'json',//配置响应数据格式
					timeout:2000,//指定超时的时间
					success:(result,reponseText,xhr)=>{
						console.log(result,reponseText,xhr);
						content.append(`<div>汽车名:${result.name},价格:${result.price}</div>`)
					},//成功的回调
					error:(xhr)=>{console.log('请求出错了',xhr);} //失败的回调
				})

				//使用jQuery发送ajax-post(精简版)
				$.post('http://127.0.0.1:8080/test_jquery_post',{school:'atguigu'},(data)=>{
					console.log(data);
					content.append(`<div>汽车名:${data.name},价格:${data.price}</div>`)
				},'json')
			})

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

11.jsonp解决跨域(工作几乎不用,面试常问)

        1.跨域(违背了同源策略:协议名,主机名,端口号不一致)

        2.非同源受到哪些限制

                cookie不能读取

                DOM无法获得

                Ajax不能获取数据

前端定义函数函数,后端调用函数

原理:绕开了xhr,借助了<script>标签发请求不受同源策略的限制,把数据拿回来

通常用jsonp后端就用callback这个命名来用

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>Document</title>
	</head>
	<body>
		<h3>当前页面一定不要用服务器去打开,因为要制造跨域问题,用jsonp去解决</h3>
		<button id="btn">点我获取数据</button>
		<script type="text/javascript" >
			
			const btn = document.getElementById('btn')
			btn.onclick = ()=>{
				//1.创建script节点
				const scriptNode = document.createElement('script')
				//2.给节点指定src属性(请求地址)
				scriptNode.src = 'http://localhost:8080/test_jsonp?callback=peiqi'
				//3.将节点放入页面
				document.body.appendChild(scriptNode)
				//4.准备好一个函数
			 	window.peiqi = (a)=>{
					console.log(a);
				}
				//5.移除已经使用过的script节点
				document.body.removeChild(scriptNode)
			}
		</script>
		
	</body>
</html>

服务器

//引入express
const express = require('express')
const cors = require('cors')

//创建app实例对象
const app = express()
//使用中间件解析urlencoded编码形式的请求体参数
app.use(express.urlencoded({extended:true}))
//使用中间件解析json编码形式的请求体参数
app.use(express.json())
app.use(cors())

//暴露静态资源
app.use(express.static(__dirname+'/src'))

app.get('/test_jsonp',(request,response)=>{
	const {callback} = request.query//接收传入的数据window中的名字peiqi
	console.log(callback);
	const person = [{name:'tom',age:18},{name:'老刘',age:5}]
	response.send(`${callback}(${JSON.stringify(person)})`)
})

面试:

1.json和jsonp有关系吗?

有一定关系,但是这两个是两回事。json是存储和交互数据的格式,jsonp是后端解决跨域的方式,为什么说他两有关系呢是因为后端返回数据必须打成JOSN字符串。例如:${JSON.stringify(person)

2.用jsonp解决跨域也是用到xhr是吗?

完全没有用到

3.用jsonp解决跨域有哪些缺点?

1.后端必须配合前端把数据转换成JOSN格式(${JSON.stringify(person))

2..后端必须配合前端写成函数调用形式${callback}()

12. jquery封装的jsonp

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>Document</title>
		<script type="text/javascript" src="./js/jquery.min.js"></script>
	</head>
	<body>
		<h3>当前页面一定不要用服务器去打开,因为要制造跨域问题,jquery封装的jsonp</h3>
		<button id="btn">点我获取数据</button>
		<script type="text/javascript" >
			const btn = $('#btn')
			btn.click(()=>{
				$.getJSON('http://localhost:8080/test_jsonp?callback=?',{},(data)=>{
					console.log(data);
				})
			})
		</script>
		
	</body>
</html>

13.cors解决跨域

        1.前端人员无需进行特殊操作

        2.用Access解决跨域不是一个两个响应头就能解决,需要一组响应头解决

       列如: response.setHeader('Access-Control-Allow-Origin','*')   【面试时问跨域问题的响应头建议写这个】

                   response.setHeader('Access-Control-Expose-Headers','*')

                   response.setHeader('Access-Control-Allow-Methods','*')

        3.put delete这两个请求都属于复杂请求,这些请求在真正请求之前都需要嗅探请求(也 可以叫做预请求)

安装yarn  add cors中间件,用与在espress解决跨域问题,

app.use(cors())使用中间件,全局都能使用了,可以随便请求了


服务器

//引入express
const express = require('express')
const cors = require('cors')

//创建app实例对象
const app = express()
//使用中间件解析urlencoded编码形式的请求体参数
app.use(express.urlencoded({extended:true}))
//使用中间件解析json编码形式的请求体参数
app.use(express.json())
app.use(cors())//全局都使用响应头

//暴露静态资源
app.use(express.static(__dirname+'/src'))

//响应GET请求--可以接收query参数
app.get('/test_get',(request,response)=>{
	console.log('有人请求test_get了--携带的query参数是:',request.query);
	/* response.setHeader('Access-Control-Allow-Origin','*')//*代表全部路径,也可以替换为具体的路径
	response.setHeader('Access-Control-Expose-Headers','*') */
	response.send('hello_test_get')
})

/* app.options('/test_put',(request,response)=>{
	response.setHeader('Access-Control-Allow-Origin','*')
	response.setHeader('Access-Control-Expose-Headers','*')
	response.setHeader('Access-Control-Allow-Methods','*')
	response.send()
}) */

app.put('/test_put',(request,response)=>{
/* 	response.setHeader('Access-Control-Allow-Origin','*')
	response.setHeader('Access-Control-Expose-Headers','*') */
	response.send('hello_test_put')
})

测试cors解决跨域

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>测试cors解决跨域</title>
	</head>
	<body>
		<h3>当前页面一定不要用服务器去打开,因为要制造跨域问题,测试cors解决跨域</h3>
		<button id="btn">点我获取数据</button>
		<script type="text/javascript" >
			const btn = document.getElementById('btn')
			btn.onclick = ()=>{
				const xhr = new XMLHttpRequest()
				xhr.onreadystatechange = ()=>{
					if(xhr.readyState === 4){
						if(xhr.status === 200){
							console.log(xhr.response);
							console.log(xhr.getAllResponseHeaders());
						}
					}
				}
				xhr.open('PUT','http://localhost:8080/test_put')
				xhr.send()
			}
		</script>
		
	</body>
</html>

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值