异步通信技术AJAX | JSON、XML的数据交换
目录
一:快速搞定AJAX(第二篇)
1、JS中如何创建和访问JSON对象
(1)在javascript语言中怎么创建一个json对象,语法是什么?
"属性名" : 属性值, "属性名" : 属性值.........的格式!
注意:属性值的数据类型随意;可能是数字,可能是布尔类型,可能是字符串,可能是数组,也可能是一个json对象.....
-
<!DOCTYPE html>
-
<html lang="en">
-
<head>
-
<meta charset="UTF-8">
-
<title>Title</title>
-
</head>
-
<body>
-
<script type="text/javascript">
-
// 先创建一个JSON对象
-
var address = {
-
"city" :"安徽",
-
"street" : "城关镇",
-
"zipcode" : "123"
-
}
-
-
// 另一个JSON对象
-
var user = {
-
"usercode" : 111,
-
"username" : "zhangsan",
-
"sex" : true,
-
"age" : 20,
-
"aihao" : ["抽烟","喝酒","烫头"],
-
"addr" : address
-
}
-
-
// 上面就等价于
-
var user = {
-
"usercode" : 111,
-
"username" : "zhangsan",
-
"sex" : true,
-
"age" : 20,
-
"aihao" : ["抽烟","喝酒","烫头"],
-
"addr" :{
-
"usercode" : 111,
-
"username" : "zhangsan",
-
"sex" : true,
-
"age" : 20,
-
"aihao" : ["抽烟","喝酒","烫头"],
-
"addr" : address}
-
}
-
-
-
</script>
-
</body>
-
</html>
(2)如何去访问json对象?主要有两种方式:
第一种方式:使用 .属性名 的方式
第二种方式:使用 ["属性名"] 的方式
-
// 第一种方式
-
console.log(address.city);
-
console.log(user.addr.street);
-
for (var i = 0;i<user.aihao.length;i ){
-
console.log(user.aihao[i]);
-
}
-
// 第二种方式
-
console.log(address["city"]);
-
console.log(user["sex"]?"男":"女");
2、基于JSON的数据交换(重点)
(1)将JSON格式字符串转换为JSON对象
我们知道从后端java程序中响应回来的是字符串(json格式的字符串),那么你怎么把json格式的字符串转换成json对象呢?主要有两种方式:
JSON格式的字符串
-
-
var fromJavaServerJsonStr = "{"usercode" : 111, "age" : 20}";
-
// \是转义字符的作用,防止与外面的双引号冲突
-
var fromJavaServerJsonStr = "{\"usercode\" : 111, \"age\" : 20}";
第一种方式:使用eval函数
-
window.eval("var jsonobj1 = " fromJavaServerJsonStr);
-
// 进行访问
-
alert(jsonobj1.usercode); // 111
第二种方式:调用javascript语言中的内置对象JSON的一个方法parse。
-
var jsonobj2 = JSON.parse(fromJavaServerJsonStr);
-
alert(jsonobj2.age); // 20
(2)基于JSON的数据交换
①对于后端,不在写html的代码,只负责把数据以JSON格式的字符串返回;后端变轻松了。
②对于前端,负责把接收到的JSON格式的字符串转换成JSON对象,并完成拼串的操作;前端变复杂了。
③整体上,后端只会出现后端的代码,前端只会出现前端的代码,便于维护!
第一种方式:对于静态的字符串
后端得到静态的数据,不在拼接HTML程序(写前端代码),只负责把数据响应回去,拼接成JSON格式的字符串
-
StringBuilder html = new StringBuilder();
-
html.append("<tr>");
-
html.append("<td>1</td>");
-
html.append("<td>王五</td>");
-
html.append("<td>20</td>");
-
html.append("<td>北京大兴区</td>");
-
html.append("</tr>");
-
html.append("<tr>");
-
html.append("<td>2</td>");
-
html.append("<td>李四</td>");
-
html.append("<td>22</td>");
-
html.append("<td>北京海淀区</td>");
-
html.append("</tr>");
-
-
// --------------------------------------------修改为
-
-
// 将以上程序拼接HTML,换成拼接JSON格式的字符串。
-
String jsonStr = "[{\"name\":\"王五\",\"age\":20,\"addr\":\"北京大兴区\"}, {\"name\":\"李四\",\"age\":22,\"addr\":\"北京海淀区\"}]";
-
// 响应JSON格式的字符串给前端。
-
out.print(jsonStr);
前端不在直接拿后端拼好的字符串格式,而是拿到JSON格式的字符串进行处理,在前端进行拼串
-
document.getElementById("stutbody").innerHTML = this.responseText
-
// -----------------------------------修改为
-
// 将json格式的字符串转换成json对象
-
var stuList = JSON.parse(this.responseText);
-
// 是一个数组,并且数组中有多个学生数据
-
var html = ""
-
for (var i = 0; i < stuList.length; i ) {
-
var stu = stuList[i]
-
html = "<tr>"
-
html = "<td>" (i 1) "</td>"
-
html = "<td>" stu.name "</td>"
-
html = "<td>" stu.age "</td>"
-
html = "<td>" stu.addr "</td>"
-
html = "</tr>"
-
}
-
document.getElementById("stutbody").innerHTML = html
第二种方式:连接数据库动态拼接JSON字符串
①创建数据库表
②后端连接数据库,拼接成JSON格式的字符串
-
package com.bjpowernode.javaweb.ajax;
-
-
import javax.servlet.ServletException;
-
import javax.servlet.annotation.WebServlet;
-
import javax.servlet.http.HttpServlet;
-
import javax.servlet.http.HttpServletRequest;
-
import javax.servlet.http.HttpServletResponse;
-
import java.io.IOException;
-
import java.io.PrintWriter;
-
import java.sql.*;
-
-
/**
-
* @Author:朗朗乾坤
-
* @Package:com.bjpowernode.javaweb.ajax
-
* @Project:ajax
-
* @name:AjaxRequest5Servlet
-
* @Date:2022/12/6 17:13
-
*/
-
-
public class AjaxRequest5Servlet extends HttpServlet {
-
-
protected void doGet(HttpServletRequest request, HttpServletResponse response)
-
throws ServletException, IOException {
-
// 响应到浏览器
-
response.setContentType("text/html;charset=UTF-8");
-
PrintWriter out = response.getWriter();
-
-
// 用于拼接成JSON的字符串
-
StringBuffer json = new StringBuffer();
-
String jsonobj = "";
-
// 连接数据库
-
Connection conn = null;
-
PreparedStatement ps = null;
-
ResultSet rs = null;
-
try {
-
// 注册驱动
-
Class.forName("com.mysql.jdbc.Driver");
-
// 获取连接
-
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC", "root", "123");
-
// 获取预编译的数据库操作对象
-
String sql = "select name,age,addr from t_student ";
-
ps = conn.prepareStatement(sql);
-
// 执行sql
-
rs = ps.executeQuery();
-
// 处理查询结果集
-
json.append("[");
-
while (rs.next()) { // 每循环一次,就拼接一次
-
String name = rs.getString("name");
-
String age = rs.getString("age");
-
String addr = rs.getString("addr");
-
// 拼成JSON格式的字符串对象,每次循环拼接的格式如下
-
// {"name":" 王五 ","age": 20 ,"addr":" 北京大兴区 "},
-
json.append(" {\"name\":\"");
-
json.append(name);
-
json.append("\",\"age\":");
-
json.append(age);
-
json.append(",\"addr\":\"");
-
json.append(addr);
-
json.append("\"},");
-
}
-
// 上面这样拼接,最后一个JSON格式的对象会多一个逗号,所以进行截串
-
jsonobj = json.substring(0,json.length()-1) "]";
-
-
} catch (ClassNotFoundException e) {
-
e.printStackTrace();
-
} catch (SQLException e) {
-
e.printStackTrace();
-
} finally {
-
// 释放资源
-
if (rs != null) {
-
try {
-
rs.close();
-
} catch (SQLException e) {
-
e.printStackTrace();
-
}
-
}
-
if (ps != null) {
-
try {
-
ps.close();
-
} catch (SQLException e) {
-
e.printStackTrace();
-
}
-
}
-
if (conn != null) {
-
try {
-
conn.close();
-
} catch (SQLException e) {
-
e.printStackTrace();
-
}
-
}
-
}
-
// 响应JSON格式的字符串给前端
-
out.print(jsonobj);
-
}
-
}
③前端对JSON格式的字符串进行处理,然后拼串
-
-
<html lang="en">
-
<head>
-
<meta charset="UTF-8">
-
<title>发送AJAX请求,显示学生列表</title>
-
</head>
-
<body>
-
<script type="text/javascript">
-
window.onload = function () {
-
document.getElementById("btn").onclick = function () {
-
// 1.创建核心对象
-
var xhr = new XMLHttpRequest();
-
// 2.注册回调函数
-
xhr.onreadystatechange = function () {
-
if (this.readyState == 4) {
-
if (this.status == 200) {
-
//document.getElementById("mybody").innerHTML = this.responseText
-
// 将json格式的字符串转换成json对象
-
var stuList = JSON.parse(this.responseText)
-
// 是一个数组,并且数组中有多个学生数据
-
var html = ""
-
for (var i = 0; i < stuList.length; i ) {
-
var stu = stuList[i]
-
html = "<tr>"
-
html = "<td>" (i 1) "</td>"
-
html = "<td>" stu.name "</td>"
-
html = "<td>" stu.age "</td>"
-
html = "<td>" stu.addr "</td>"
-
html = "</tr>"
-
}
-
document.getElementById("mybody").innerHTML = html
-
} else {
-
alert(this.status)
-
}
-
}
-
}
-
// 3.开启通道
-
xhr.open("GET", "/ajax/ajaxrequest5", true)
-
// 4.发送请求
-
xhr.send()
-
}
-
}
-
</script>
-
-
<input type="button" value="显示学员列表" id="btn">
-
<table border="1px" width="50%">
-
<tr>
-
<th>序号</th>
-
<th>姓名</th>
-
<th>年龄</th>
-
<th>住址</th>
-
</tr>
-
<!--具体的内容需要连接数据库动态获取,为了便于操作,写一个tbody-->
-
<tbody id="mybody">
-
<!--具体内容响应在这里-->
-
</tbody>
-
-
</table>
-
-
-
</body>
-
</html>
④效果展示,点击按钮
(3)fastjson组件优化代码
从上面代码来看,拼接JSON格式的字符串太痛苦,可以使用阿里巴巴的fastjson组件,它可以将java对象转换成json格式的字符串
😊测试通过fastjson对象转换为JSON格式字符串
①引入jar包,并在项目依赖中也要引入
②创建一个User类
-
package com.bjpowernode.javaweb.fastjson;
-
-
public class User {
-
private String id;
-
private String username;
-
private int age;
-
-
public User() {
-
}
-
-
public User(String id, String username, int age) {
-
this.id = id;
-
this.username = username;
-
this.age = age;
-
}
-
-
public String getId() {
-
return id;
-
}
-
-
public void setId(String id) {
-
this.id = id;
-
}
-
-
public String getUsername() {
-
return username;
-
}
-
-
public void setUsername(String username) {
-
this.username = username;
-
}
-
-
public int getAge() {
-
return age;
-
}
-
-
public void setAge(int age) {
-
this.age = age;
-
}
-
}
③进行测试;JSON类中的方法都是静态的方法,直接调用即可
-
package com.bjpowernode.javaweb.fastjson;
-
-
import com.alibaba.fastjson.JSON;
-
-
import java.util.ArrayList;
-
import java.util.List;
-
-
-
public class FastjsonTest {
-
public static void main(String[] args) {
-
// 创建一个User类型的对象
-
User user1 = new User("111", "zhangsan", 20);
-
// 将以上的User对象转换成json格式的字符串
-
// JSON类中的方法都是静态的方法,直接调用即可。
-
String jsonSTr = JSON.toJSONString(user1);
-
System.out.println(jsonSTr);
-
-
// 在创建一个对象,放入集合当中,看会不会转换成JSON格式的数组
-
User user2 = new User("222", "lisi", 20);
-
// 创建一个集合
-
ArrayList<User> userList = new ArrayList<>();
-
// 把数据添加进去
-
userList.add(user1);
-
userList.add(user2);
-
// 转换成JSON对象的数组
-
String jsonStr2 = JSON.toJSONString(userList);
-
System.out.println(jsonStr2);
-
-
}
-
}
④测试结果如下
😊通过fastjson组件替换手动拼串成JSON格式的对象
思考:我们从数据库中取出来的数据都是零散的,所以我们每次取到的数据封装成一个Student对象,然后在把这个对象放入一个集合当中;最终把通过这个集合调用JSON.toJSONString方法,把数据转换成JSON格式的对象!
①Student类
-
package com.bjpowernode.javaweb.bean;
-
-
-
public class Student {
-
private String name;
-
private int age;
-
private String addr;
-
-
public Student() {
-
}
-
-
public Student(String name, int age, String addr) {
-
this.name = name;
-
this.age = age;
-
this.addr = addr;
-
}
-
-
public String getName() {
-
return name;
-
}
-
-
public void setName(String name) {
-
this.name = name;
-
}
-
-
public int getAge() {
-
return age;
-
}
-
-
public void setAge(int age) {
-
this.age = age;
-
}
-
-
public String getAddr() {
-
return addr;
-
}
-
-
public void setAddr(String addr) {
-
this.addr = addr;
-
}
-
}
②后端代码进行优化
-
package com.bjpowernode.javaweb.ajax;
-
-
import com.alibaba.fastjson.JSON;
-
import com.bjpowernode.javaweb.bean.Student;
-
-
import javax.servlet.ServletException;
-
import javax.servlet.annotation.WebServlet;
-
import javax.servlet.http.HttpServlet;
-
import javax.servlet.http.HttpServletRequest;
-
import javax.servlet.http.HttpServletResponse;
-
import java.io.IOException;
-
import java.io.PrintWriter;
-
import java.sql.*;
-
import java.util.ArrayList;
-
import java.util.List;
-
-
/**
-
* @Author:朗朗乾坤
-
* @Package:com.bjpowernode.javaweb.ajax
-
* @Project:ajax
-
* @name:AjaxRequest5Servlet
-
* @Date:2022/12/6 17:13
-
*/
-
-
public class AjaxRequest5Servlet extends HttpServlet {
-
-
protected void doGet(HttpServletRequest request, HttpServletResponse response)
-
throws ServletException, IOException {
-
// 响应到浏览器
-
response.setContentType("text/html;charset=UTF-8");
-
PrintWriter out = response.getWriter();
-
-
// 用于拼接成JSON的字符串
-
// StringBuffer json = new StringBuffer();
-
String jsonobj = "";
-
// 连接数据库
-
Connection conn = null;
-
PreparedStatement ps = null;
-
ResultSet rs = null;
-
try {
-
// 注册驱动
-
Class.forName("com.mysql.jdbc.Driver");
-
// 获取连接
-
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC", "root", "123");
-
// 获取预编译的数据库操作对象
-
String sql = "select name,age,addr from t_student ";
-
ps = conn.prepareStatement(sql);
-
// 执行sql
-
rs = ps.executeQuery();
-
// 处理查询结果集
-
/*json.append("[");
-
while (rs.next()) { // 每循环一次,就拼接一次
-
String name = rs.getString("name");
-
String age = rs.getString("age");
-
String addr = rs.getString("addr");
-
// 拼成JSON格式的字符串对象,每次循环拼接的格式如下
-
// {"name":" 王五 ","age": 20 ,"addr":" 北京大兴区 "},
-
json.append(" {\"name\":\"");
-
json.append(name);
-
json.append("\",\"age\":");
-
json.append(age);
-
json.append(",\"addr\":\"");
-
json.append(addr);
-
json.append("\"},");
-
}
-
// 上面这样拼接,最后一个JSON格式的对象会多一个逗号,所以进行截串
-
jsonobj = json.substring(0,json.length()-1) "]";*/
-
-
// 创建一个集合
-
List<Student> studentList = new ArrayList<>();
-
while (rs.next()) {
-
String name = rs.getString("name");
-
int age = rs.getInt("age");
-
String addr = rs.getString("addr");
-
// 将以上数据封装成Student对象
-
Student s = new Student(name, age, addr);
-
// 将Student对象放到List集合
-
studentList.add(s);
-
}
-
// 将List集合转换成json字符串
-
jsonobj = JSON.toJSONString(studentList);
-
-
} catch (ClassNotFoundException e) {
-
e.printStackTrace();
-
} catch (SQLException e) {
-
e.printStackTrace();
-
} finally {
-
// 释放资源
-
if (rs != null) {
-
try {
-
rs.close();
-
} catch (SQLException e) {
-
e.printStackTrace();
-
}
-
}
-
if (ps != null) {
-
try {
-
ps.close();
-
} catch (SQLException e) {
-
e.printStackTrace();
-
}
-
}
-
if (conn != null) {
-
try {
-
conn.close();
-
} catch (SQLException e) {
-
e.printStackTrace();
-
}
-
}
-
}
-
// 响应JSON格式的字符串给前端
-
out.print(jsonobj);
-
}
-
}
③前端代码不变
-
-
<html lang="en">
-
<head>
-
<meta charset="UTF-8">
-
<title>发送AJAX请求,显示学生列表</title>
-
</head>
-
<body>
-
<script type="text/javascript">
-
window.onload = function () {
-
document.getElementById("btn").onclick = function () {
-
// 1.创建核心对象
-
var xhr = new XMLHttpRequest();
-
// 2.注册回调函数
-
xhr.onreadystatechange = function () {
-
if (this.readyState == 4) {
-
if (this.status == 200) {
-
//document.getElementById("mybody").innerHTML = this.responseText
-
// 将json格式的字符串转换成json对象
-
var stuList = JSON.parse(this.responseText)
-
// 是一个数组,并且数组中有多个学生数据
-
var html = ""
-
for (var i = 0; i < stuList.length; i ) {
-
var stu = stuList[i]
-
html = "<tr>"
-
html = "<td>" (i 1) "</td>"
-
html = "<td>" stu.name "</td>"
-
html = "<td>" stu.age "</td>"
-
html = "<td>" stu.addr "</td>"
-
html = "</tr>"
-
}
-
document.getElementById("mybody").innerHTML = html
-
} else {
-
alert(this.status)
-
}
-
}
-
}
-
// 3.开启通道
-
xhr.open("GET", "/ajax/ajaxrequest5", true)
-
// 4.发送请求
-
xhr.send()
-
}
-
}
-
</script>
-
-
<input type="button" value="显示学员列表" id="btn">
-
<table border="1px" width="50%">
-
<tr>
-
<th>序号</th>
-
<th>姓名</th>
-
<th>年龄</th>
-
<th>住址</th>
-
</tr>
-
<!--具体的内容需要连接数据库动态获取,为了便于操作,写一个tbody-->
-
<tbody id="mybody">
-
<!--具体内容响应在这里-->
-
</tbody>
-
-
</table>
-
-
-
</body>
-
</html>
3、基于XML的数据交换(了解)
xml和JSON都是常用的数据交换格式
①XML体积大,解析麻烦;较少用。
②JSON体积小,解析简单;较常用。
(1)对于以下XML文件,进行数据的交换
-
<students>
-
<student>
-
<name>zhangsan</name>
-
<age>20</age>
-
</student>
-
<student>
-
<name>lisi</name>
-
<age>22</age>
-
</student>
-
</students>
(2)后端代码
注意:如果服务器端响应XML的话,响应的内容类型需要写成xml。不常用我们就不连接数据库了!
response.setContentType("text/xml;charset=UTF-8");
-
package com.bjpowernode.javaweb.ajax;
-
-
import javax.servlet.ServletException;
-
import javax.servlet.annotation.WebServlet;
-
import javax.servlet.http.HttpServlet;
-
import javax.servlet.http.HttpServletRequest;
-
import javax.servlet.http.HttpServletResponse;
-
import java.io.IOException;
-
import java.io.PrintWriter;
-
-
/**
-
* @Author:朗朗乾坤
-
* @Package:com.bjpowernode.javaweb.ajax
-
* @Project:ajax
-
* @name:AjaxRequest6Servlet
-
* @Date:2022/12/7 16:26
-
*/
-
-
public class AjaxRequest6Servlet extends HttpServlet {
-
-
protected void doGet(HttpServletRequest request, HttpServletResponse response)
-
throws ServletException, IOException {
-
// 设置响应的类型是XML
-
response.setContentType("text/xml;charset=UTF-8");
-
PrintWriter out = response.getWriter();
-
-
// 进行拼串
-
StringBuilder xml = new StringBuilder();
-
xml.append("<students>");
-
xml.append("<student>");
-
xml.append("<name>zhangsan</name>");
-
xml.append("<age>20</age>");
-
xml.append("</student>");
-
xml.append("<student>");
-
xml.append("<name>lisi</name>");
-
xml.append("<age>22</age>");
-
xml.append("</student>");
-
xml.append("</students>");
-
-
// 响应到给前端
-
out.print(xml);
-
-
-
}
-
}
(3)前端代码
①使用responseXML方法接收对象,自动封装为文档对象(xmlDoc)
②通过这个对象调用getElementsByTagName("student")方法,获取所有<student>的标签,肯定是一个数组;然后遍历数组,拿到每一个<student>的标签
③再调用childNodes方法,拿到<student>标签的所有子元素,也是是一个数组,需要再次遍历,拿到每个子元素或者子节点node;然后子节点调用nodeName方法,看是不是name或者age属性,如果是就调用子节点的textContent方法拿到对应的数据,拼串拼进去。
④最后把整个拼好的字符串扔到table里面进行输出!
-
-
<html lang="en">
-
<head>
-
<meta charset="UTF-8">
-
<title>使用XML完成数据交换</title>
-
</head>
-
<body>
-
<script type="text/javascript">
-
window.onload = function(){
-
document.getElementById("btn").onclick = function(){
-
// 1.创建XMLHTTPRequest对象
-
var xhr = new XMLHttpRequest();
-
// 2.注册回调函数
-
xhr.onreadystatechange = function () {
-
if (this.readyState == 4) {
-
if (this.status == 200) {
-
// 服务器端响应了一个XML字符串,这里怎么接收呢?
-
// 使用XMLHTTPRequest对象的responseXML属性,接收返回之后,可以自动封装成document对象(文档对象)
-
var xmlDoc = this.responseXML
-
//console.log(xmlDoc)
-
// 获取所有的<student>元素,返回了多个对象,应该是数组。
-
var students = xmlDoc.getElementsByTagName("student")
-
//console.log(students[0].nodeName)
-
var html = "";
-
for (var i = 0; i < students.length; i ) {
-
var student = students[i]
-
// 获取<student>元素下的所有子元素
-
html = "<tr>"
-
html = "<td>" (i 1) "</td>"
-
var nameOrAge = student.childNodes
-
for (var j = 0; j < nameOrAge.length; j ) {
-
var node = nameOrAge[j]
-
if (node.nodeName == "name" || node.nodeName == "age") {
-
//console.log("name = " node.textContent)
-
html = "<td>" node.textContent "</td>"
-
}
-
/*if (node.nodeName == "age") {
-
//console.log("age = " node.textContent)
-
html = "<td>" node.textContent "</td>"
-
}*/
-
}
-
html = "</tr>"
-
}
-
document.getElementById("stutbody").innerHTML = html
-
}else{
-
alert(this.status)
-
}
-
}
-
}
-
// 3.开启通道
-
xhr.open("GET", "/ajax/ajaxrequest6?t=" new Date().getTime(), true)
-
// 4.发送请求
-
xhr.send()
-
}
-
}
-
</script>
-
<button id="btn">显示学生列表</button>
-
<table width="500px" border="1px">
-
<thead>
-
<tr>
-
<th>序号</th>
-
<th>姓名</th>
-
<th>年龄</th>
-
</tr>
-
</thead>
-
<tbody id="stutbody">
-
-
</tr>
-
</tbody>
-
</table>
-
</body>
-
</html>
(4)执行效果如下:点击按钮,展示数据
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgaehhj
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
photoshop蒙版画笔没反应怎么办
PHP中文网 06-24