位置: IT常识 - 正文

【原生Ajax】全面了解xhr的概念与使用。(原生ajax和axios的区别)

编辑:rootadmin
【原生Ajax】全面了解xhr的概念与使用。

推荐整理分享【原生Ajax】全面了解xhr的概念与使用。(原生ajax和axios的区别),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:原生ajax步骤,原生ajax请求兼容写法,ajax 原生js,原生ajax和axios的区别,ajax 原生js,原生 ajax,原生 ajax,原生ajax写法,内容如对您有帮助,希望把文章链接给更多的朋友!

✍️ 作者简介: 前端新手学习中。

💂 作者主页: 作者主页查看更多前端教学

🎓 专栏分享:css重难点教学   Node.js教学 从头开始学习   ajax学习

文章目录XHR的基本使用  什么是XHR  使用xhr发起GET请求  了解xhr对象的readyState属性  使用xhr发起带参数的GET请求  URL编码与解码    什么是URL编码    如何对URL进行编码与解码  使用xhr发起post请求数据交换格式  什么是数据交换格式  XML    什么是XML    XML和HTML的区别    XML的缺点  JSON    什么是JSON    JSON的两种结构    JSON语法的注意事项    JSON和JS对象的关系    JSON和JS对象的互转    序列化和反序列化封装自己的Ajax函数  要实现的效果  处理data参数  定义itheima函数  判断请求的类型xhr level2的新特性  旧版xhr的缺点  xhr levle2的新特性    设置http请求时限。    FormData对象管理表单数据    上传文件XHR的基本使用  什么是XHR

xhr是浏览器提供的JavaScript对象,通过它,可以请求服务器上的数据资源,之前所学的jquery的ajax函数,就是基于xhr对象封装出来的。

  使用xhr发起GET请求

步骤 1.创建xhr对象 2.使用xhr.open()函数 3.调用xhr.send()函数 4.监听xhr.onreadystatechange事件。

//创建xhr对象 let xhr = new XMLHttpRequest(); //调用open函数 xhr.open('get', 'http://www.liulongbin.top:3006/api/getbooks') //调用send函数 xhr.send() //监听事件 xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status === 200) { //获取成功 console.log(xhr.responseText); } }

  了解xhr对象的readyState属性

XHR对象的readyState属性,用来表示当前Ajax请求所处的状态,每个Ajax请求必然处于一下状态中的一个:

值状态描述0UNSENTXMLHttpRequest对象已被创建,但尚未调用open方法。1OPENEDopen()方法已经被调用2HEADERS_RECEIVEDsend()方法已经被调用,响应头也已经接受3LOADING数据接受中,此时response属性中已经包含部分数据4DONEAjax请求完成,这意味着数据传输已经彻底完成或失败  使用xhr发起带参数的GET请求

使用xhr对象发起带参数的get请求时,只需在调用xhr.open期间,为URL地址指定参数即可,在地址后面写上?后面以键值对的形式写上数据,多个数据用&连接。

//创建xhr对象 let xhr = new XMLHttpRequest(); //调用open函数 xhr.open('get', 'http://www.liulongbin.top:3006/api/getbooks?id=1') //调用send函数 xhr.send() //监听事件 xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status === 200) { //获取成功 console.log(xhr.responseText); } }

  URL编码与解码    什么是URL编码

URL地址中,只允许出现英文相关的字母,标点符号,数字,因此。在URL地址中不允许出现中文字符。 如果URL中需要包含中文这样的字符,则必须对中文字符进行编码(转义)。 URL编码的原则,使用安全的字符,(没有特殊用途或者特殊意义的可打印字符)去表示那些不安全的字符。

    如何对URL进行编码与解码

浏览器提供了URL编码与解码的API,分别是:

encodeURI() 编码的函数decodeURI()解码的函数 let str = '黑马程序员'; let str2 = encodeURI(str) console.log(str2); //utf-8一个汉字占三个字节 ,写六个是黑马两个字。 let str3 = decodeURI('%E9%BB%91%E9%A9%AC') let str4 = decodeURI(str2) console.log(str3); console.log(str4);

  使用xhr发起post请求

步骤 1.创建xhr对象 2.调用xhr.open()函数 3.设置Content-Type属性(固定写法) 4.调用xhr.send()函数。同时指定要发送的数据。 5.监听xhr.onreadystatechange事件

//创建xhr对象 let xhr = new XMLHttpRequest(); //调用open() xhr.open('post', 'http://www.liulongbin.top:3006/api/addbook'); //设置Content-Type(固定写法) xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); //调用send函数 xhr.send('bookname=水浒传&author=施耐庵&publisher=上海图书出版社') //监听事件 xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status === 200) { console.log(xhr.responseText); } }

数据交换格式  什么是数据交换格式

数据交换格式,就是服务器端与客户端之间进行数据传输与交换的格式.

前端领域,经常提及的两种数据交换格式分别是XML和JSON。其中XML用的非常少,所以,我们重点要学习的数据交换格式JSON。

  XML    什么是XML

xml的英文全称是EXtensible Markup Language,即可扩展标记语言,因此,XML和HTML类似,也是一种标记语言。

    XML和HTML的区别

xml和html虽然都是标记语言,但是,他们两者之间没有任何的关系。

HTML被设计用来描述网页上的内容,是网页内容的载体XML被设计用来传输和存储数据,是数据的载体

    XML的缺点

1.XML格式臃肿,和数据无关的代码多,体积大,传输效率低。 2.在JavaScript中解析XML比较麻烦。

  JSON    什么是JSON

概念:JSON的英文全称是JavaScript Object Notation,即 JavaScript对象表示法。简单来讲,JSON就是JavaScript对象和数组的字符串表示法,它使用文本表示一个JS对象或数组的信息,因此,JSON的本质是字符串。

作用:JSON是一种轻量级的文本数据交换格式,在作用上类似XML,专门用于存储和传输数据,单是JSON比XML更小,更快,更易解析。

现状:JSON是在2001年开始被推广和使用的数据格式,到现今为止,JSON已经成为了主流的数据交换格式。

    JSON的两种结构

JSON就是用字符串来表示JavaScript的对象和数组两种结构,通过这两种结构的相互嵌套,可以表示各种复杂的数据结构。

对象结构:对象结构在JSON中表示为{}括起来的内容,数据结构为{key:value,key:value,…}的键值对结构,其中,key必须是使用英文的双引号包裹的字符串,value的数据类型可以是数字,字符串,布尔值,null,数组,对象六种类型。数组结构:数组结构在JSON中表示为[]括起来的内容,数据结构为[‘java’,‘javascript’,30,true],数组中数据的类型可以是数字,字符串,布尔值,null,数组,对象6种类型。    JSON语法的注意事项

1.属性名必须使用双引号包裹。 2.字符串类型的值必须使用双引号包裹 3.JSON中不允许使用单引号表示字符串 4.JSON中不能写注释 5.JSON的最外层必须是对象或数组格式。 6.不能使用undefined或函数作为JSON的值

【原生Ajax】全面了解xhr的概念与使用。(原生ajax和axios的区别)

JSON的作用:在计算机与网络之间存储和传输数据。 JSON的本质:用字符串来表示JavaScript对象数据或数组数据。

    JSON和JS对象的关系

JSON是js对象的字符串表示法,它使用文本表示一个js对象的信息,本质是一个字符串。例如:

var jsobj ={a:'hello',b:'world'}var jsonstr = '{'a':'hello','b':'world'}'    JSON和JS对象的互转

要实现从JSON字符串转换为js对象,使用JSON.parse()方法;

var xhr = new XMLHttpRequest(); xhr.open('get', 'http://www.liulongbin.top:3006/api/getbooks'); xhr.send(); xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status === 200) { console.log(xhr.responseText); var restr = JSON.parse(xhr.responseText) console.log(restr); } }

要实现从JS对象转换为JSON字符串,使用JSON.stringify()方法:

    序列化和反序列化

把数据对象转换为字符串的过程,叫做序列化,例如:调用JSON.stringify()函数的操作,叫做JSON序列化。

把字符串转换为数据对象的过程,叫做反序列化,例如:调用JSON.parse()函数的操作,叫做JSON的反序列化。

封装自己的Ajax函数  要实现的效果

定义一个名为itheima的ajax函数,导入js文件之后,可以进行调用文件内的相关函数。 定义options参数选项 itheima()函数是我们自定义的Ajax函数,它接受一个配置对象作为参数,配置对象中可以配置如下属性:

method 请求的类型url 请求的URL地址data 请求携带的数据success 请求成功之后的回调函数  处理data参数

需要把data对象,转化成查询字符串的格式,从而提交给服务器,因此提前定义resolveData函数如下:

function resolveData(data) { var arr = []; for (const k in data) { //这里说一下对象的调用方法,对象调用可以使用【】和点,这里的对象调用需要用【】的,可以理解为.属性名,表达的是直接的属性名,这里的k是一个变量,.k的意思是对象里的k键名,而不是变量的值,使用【k】可以获取k对应的值。 //我们可以先进行字符串链接data.k再使用eval方法进行解析,就可以使用点调用了 // var str = k + '=' + eval("data." + k); var str = k + '=' + data[k]; arr.push(str); } return arr.join('&')}var str = resolveData({ name: 'xiaoxie', age: 20 });console.log(str);

  定义itheima函数

在itheima()函数中,需要创建xhr对象,并监听onreadystatechange事件。

function itheima(options) { let xhr = new XMLHttpRequest(); let qs = resolveData(options.data)--------判断类型 发起请求 代码-------------- xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status === 200) { let result = JSON.parse(xhr.responseText) options.success(result) } }}  判断请求的类型

不同的请求类型,对应的xhr对象的不同操作,因此需要对请求类型进行if…else…的判断。

if (options.method.toUpperCase() === 'GET') { xhr.open('get', options.URL + '?' + qs) xhr.send(); } else if (options.method.toUpperCase() === 'POST') { xhr.open('post', options.URL) xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded') xhr.send(qs); }

xhr level2的新特性  旧版xhr的缺点只支持文本数据的传输,无法用来读取和上传文件。传送和接受数据时,没有进度信息,只能提示有没有完成。  xhr levle2的新特性可以设置http请求的时限。可以使用formdata对象管理表单数据可以上传文件可以获得数据传输的进度信息。    设置http请求时限。

有时,Ajax操作很耗时,而且无法预知要花多少时间。如果网速很慢,用户可能要等很久,新版本的xhr对象,增加了timeout属性,可以设置http请求的时限:

xhr.timeout = 3000

上面的语句,将最长等待时间设为3000毫秒,过了这个时限,就自动停止http请求。与之配套的还有一个timeout事件,用来指定回调函数。

xhr.ontimeout = function(event){alert('请求超时')} let xhr = new XMLHttpRequest(); xhr.timeout = 30; xhr.ontimeout = function () { console.log(请求超时); } xhr.open('get', 'http://liulongbin.top:3006/api/getbooks') xhr.send() xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status == 200) { console.log(xhr.responseText); } }

    FormData对象管理表单数据

Ajax操作往往用来提交表单数据。为了方便表单处理,HTML5新增了一个FormData对象,可以模拟表单操作。

let fd = new FormData(); fd.append('uname', 'xiaoxie') fd.append('pwd', 123456) let xhr = new XMLHttpRequest(); xhr.open('post', 'http://www.liulongbin.top:3006/api/formdata') xhr.send(fd); xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status == 200) { console.log(JSON.parse(xhr.responseText)); } }

FormData对象也可以用来获取网页表单的值,不用通过serialize()方法转换,可以获取值后可以直接使用,不用通过示例代码如下:

var form = document.querySelector('#form1') form.addEventListener('submit', function (e) { e.preventDefault(); //创建对象,获取数据。 let fd = new FormData(form); let xhr = new XMLHttpRequest(); xhr.open('post', 'http://www.liulongbin.top:3006/api/formdata') xhr.send(fd) xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status === 200) { console.log(JSON.parse(xhr.responseText)); } } })

    上传文件

新版xhr对象,不仅可以发送文本信息,还可以上传文件。

定义ui结构验证是否选择了文件向FormData中追加文件使用xhr发起上传文件的请求监听onreadystatechange事件 定义UI结构 <!-- 文件选择框 --> <input type="file" id="file1"> <!-- 上传文件的按钮 --> <button id="btnUpload"></button> <br> <img src="" alt="" id="img" width="800">

验证是否选择了文件

//获取文件上传按钮 let btn = document.getElementsByTagName('button')[0]; //为按钮绑定单击事件处理函数 btn.addEventListener('click', function () { //获取用户选择的文件鼠标 let files = document.querySelector('#file1').files; if (files.length <= 0) { return alert('请选择要上传的文件') } console.log('用户选择了待上传的文件'); })

向FormData中追加文件

let fd = new FormData() fd.append('avatar', files[0])

使用xhr发起上传文件的请求

let xhr = new XMLHttpRequest(); xhr.open('post', 'http://www.liulongbin.top:3006/api/upload/avatar') xhr.send(fd)

监听onreadystatechange事件

xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status === 200) { let data = JSON.parse(xhr.responseText) if (data.status === 200) { //上传成功 alert('上传成功') document.getElementById('img').src = 'http://www.liulongbin.top:3006' + data.url } else { console.log('图片上传失败' + data.message); } } }

显示文件上传进度

新版本的XHR对象中,可以通过监听xhr.upload.onprogress事件,来获取到文件的上传进度,语法格式如下:

//监听上传进度 xhr.upload.onprogress = function (e) { if (e.lengthComputable) { let uploadProgroess = Math.ceil((e.loaded / e.total) * 100) console.log(uploadProgroess); } }

美化进度显示

<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous"> //设置进度条$('#percent').attr('style', 'width:' + uploadProgroess).html(uploadProgroess + '%')

完整代码

<!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>Document</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous"></head><body> <!-- 文件选择框 --> <input type="file" id="file1"> <!-- 上传文件的按钮 --> <button id="btnUpload">上传文件</button> <br> <img src="" alt="" id="img" width="800"> <div class="progress" style="width: 300px;"> <div class="progress-bar progress-bar-striped active" style="width: 0%" id="percent"> 0% </div> </div> <script> //获取文件上传按钮 let btn = document.getElementsByTagName('button')[0]; //为按钮绑定单击事件处理函数 btn.addEventListener('click', function () { //获取用户选择的文件属性,是一个数组。 let files = document.querySelector('#file1').files; if (files.length <= 0) { return alert('请选择要上传的文件') } //表单中添加相应的数据 let fd = new FormData() fd.append('tupian', files[0]) //使用xhr发起上传文件的请求 let xhr = new XMLHttpRequest(); //监听上传进度 xhr.upload.onprogress = function (e) { if (e.lengthComputable) { let uploadProgroess = Math.ceil((e.loaded / e.total) * 100) console.log(uploadProgroess); //设置进度条 $('#percent').attr('style', 'width:' + uploadProgroess).html(uploadProgroess + '%') } } xhr.open('post', 'http://www.liulongbin.top:3006/api/upload/avatar') xhr.send(fd) //监听onreadystatechange事件 xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status === 200) { let data = JSON.parse(xhr.responseText) if (data.status === 200) { //上传成功 alert('上传成功') document.getElementById('img').src = 'http://www.liulongbin.top:3006' + data.url } else { console.log('图片上传失败' + data.message); } } } }) </script></body></html>

本文链接地址:https://www.jiuchutong.com/zhishi/299476.html 转载请保留说明!

上一篇:function 函数(function函数的定义)

下一篇:因果推断1--基本方法介绍(个人笔记)(因果推断的常用标准)

  • 打印机无法打印全页照片(打印机无法打印)(打印机无法打印图片是什么原因)

    打印机无法打印全页照片(打印机无法打印)(打印机无法打印图片是什么原因)

  • 手机复制粘贴怎么操作(手机复制粘贴怎么粘贴不上去)

    手机复制粘贴怎么操作(手机复制粘贴怎么粘贴不上去)

  • 抖音禁止评论在哪设置(抖音禁止评论在哪里打开)

    抖音禁止评论在哪设置(抖音禁止评论在哪里打开)

  • 淘宝卖家漏发货要怎么处理(淘宝卖家漏发货赔偿标准)

    淘宝卖家漏发货要怎么处理(淘宝卖家漏发货赔偿标准)

  • 永久删除视频如何恢复(怎样才能永久删除视频)

    永久删除视频如何恢复(怎样才能永久删除视频)

  • 京东家庭号能看到对方订单吗(京东家庭号能看到对方收货地址吗)

    京东家庭号能看到对方订单吗(京东家庭号能看到对方收货地址吗)

  • 天猫精灵反应迟钝怎么办(天猫精灵反应慢是什么原因)

    天猫精灵反应迟钝怎么办(天猫精灵反应慢是什么原因)

  • 手机后屏玻璃碎了怎么办(手机后屏玻璃碎了能充电吗)

    手机后屏玻璃碎了怎么办(手机后屏玻璃碎了能充电吗)

  • btvdl09是什么平板型号(btvdl09和btvw09)

    btvdl09是什么平板型号(btvdl09和btvw09)

  • 抖音怎么买抖币(抖音怎么买抖币更便宜)

    抖音怎么买抖币(抖音怎么买抖币更便宜)

  • 手机屏起鼓有危险吗?(手机屏起鼓有危险吗视频)

    手机屏起鼓有危险吗?(手机屏起鼓有危险吗视频)

  • 为什么二维码扫描不出来(为什么二维码扫描显示空白)

    为什么二维码扫描不出来(为什么二维码扫描显示空白)

  • nova6充电器多少瓦(nova6原装充电器多少w)

    nova6充电器多少瓦(nova6原装充电器多少w)

  • 漏型和源型的区别(什么是源型和漏型)

    漏型和源型的区别(什么是源型和漏型)

  • 乐视账号怎么解绑(乐视账号怎么强制解绑)

    乐视账号怎么解绑(乐视账号怎么强制解绑)

  • 手机怎么找回浏览器历史记录(手机怎么找回浏览器记录)

    手机怎么找回浏览器历史记录(手机怎么找回浏览器记录)

  • 淘宝新书拆封了可以换吗(新书拆封了还能退吗)

    淘宝新书拆封了可以换吗(新书拆封了还能退吗)

  • 智慧团建姓名填错怎么修改(智慧团建姓名是曾用名)

    智慧团建姓名填错怎么修改(智慧团建姓名是曾用名)

  • ppt怎样自己设计字体(如何自己设计ppt)

    ppt怎样自己设计字体(如何自己设计ppt)

  • 安卓手机如何打开.psd文件(安卓手机如何打开开发者模式)

    安卓手机如何打开.psd文件(安卓手机如何打开开发者模式)

  • 锁屏快资讯怎么删除(锁屏资讯怎么打开)

    锁屏快资讯怎么删除(锁屏资讯怎么打开)

  • p20录屏在哪里(p20屏幕录制在哪里)

    p20录屏在哪里(p20屏幕录制在哪里)

  • 全民k歌怎么发合唱邀请(全民k歌怎么发布录好的视频)

    全民k歌怎么发合唱邀请(全民k歌怎么发布录好的视频)

  • win10平板模式怎么分屏(win10平板模式怎么打开)

    win10平板模式怎么分屏(win10平板模式怎么打开)

  • MySQL 高级查询(MySQL高级查询)

    MySQL 高级查询(MySQL高级查询)

  • 比肩ChatGPT的国产AI:文心一言——有话说(比肩美国)

    比肩ChatGPT的国产AI:文心一言——有话说(比肩美国)

  • phpwind和discuz的简单对比(php windows)

    phpwind和discuz的简单对比(php windows)

  • mysql存储引擎的整理(mysql存储引擎是什么意思)

    mysql存储引擎的整理(mysql存储引擎是什么意思)

  • 印花税贴花是什么时候取消的
  • 产品模板是固定的吗
  • 免税农产品发票需要勾选吗
  • 向境外支付赔偿金需要发票么
  • 利润表中的本期金额栏内各项数字一般根据什么填列
  • 转让股权收入需要缴纳企业所得税吗
  • 房地产公司销售商品房属于增值税征收范围吗
  • 企业设备融资是什么意思?
  • 增值税和实际缴税不符
  • 工业结转成本方法有哪些?
  • 购买毛巾的费用是多少
  • 贸易公司一般纳税多少
  • 专家评审费个人所得税计算公式
  • 兼职获得员工旅游资源
  • 培训过程中出现的问题及解决办法
  • 生产企业是否可以兼营外贸业务
  • 预提费用的会计科目
  • 办公车辆汽油费计入什么科目
  • 其他专项收入怎么做账
  • 收到科技局研发的短信
  • 应交税金年终怎么计算
  • 收购自然人股东的股权要注意什么
  • 筹建期的银行利息收入分录
  • php aop
  • php 编程
  • 短期投资需要结转吗
  • 只有收据没有发票是不是逃税
  • 借出材料表
  • 免施工许可证
  • php框架yii
  • php xml转数组
  • 增值税专用发票怎么开
  • javascript手机编程
  • bit/ttagapp
  • 网络安全文章1000字
  • 小规模纳税人去年免税,红冲后今年开多少税率的发票
  • 企业之间的借款计入什么科目
  • python如何获取列表元素
  • 长期资产包含哪些
  • 可转债公允价值评估
  • 业务活动表本年累计数公式是什么
  • 下列项目的进项税额可以从销售税额中抵扣的是
  • access的数据源在哪里设置
  • 对增值税发票开具方面是有何要求?
  • 应收账款的贷方发生额表示什么
  • 以前年度多交的房产税现在收到退税款了咋做分录
  • 单位或个体经营者
  • 临时工的劳务费需要申报个税吗?
  • 企业所得税季末从业人数
  • 企业缴纳耕地占补多少
  • 存货成本主要包括
  • 资产负债表不平衡怎么办
  • 房租费会计分录
  • 固定资产小汽车折旧怎么计提
  • 公司按揭贷款
  • 小规模与一般纳税人的界定
  • 主营业务收入减少记哪方
  • 房地产企业收入确认条件税法
  • 简述Mysql Explain 命令
  • centos7内存占用大
  • ubuntu20关机卡在logo
  • macbookpro客人用户
  • win7浏览器主页怎么设置
  • win10系统电脑无限重启
  • win8初始登录账号密码
  • centos打包文件
  • cocos2d schedule
  • ajaxfrom表单提交
  • jq拖拽div替换位置
  • 了不起的女孩
  • css控制html
  • 正途科技有限公司
  • javascript模块化与非模块化开发区别
  • 云南税务网上税务局
  • 贵阳市税务局基本情况
  • 百旺税控盘口令认证失败pin锁定怎么办
  • 江苏电子票据
  • 甘肃税务厅
  • 外经证核销在公司所在地还是在项目所在地
  • 小规模纳税人的增值税怎么计算
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设