Ajax
1. Ajax
是Asynchronous JavaScript and XML的缩写,异步的JavaScript和XML. Ajax描述了一种主要使用脚本操作HTTP的Web应用架构,Ajax应用的主要特点是使用脚本操纵HTTP和Web服务器进行数据交换,不会导致页面重载。
2. HTTP
超文本传输协议(HyperText Transfer Protocol)规定了Web浏览器如何从Web服务器获取文档和向Web服务器提交表单内容,以及Web服务器如何响应这些请求和提交。通常,HTTP并不在脚本的控制下,只是当用户单击链接,提交表单和输入URL时才发生。但是,用JavaScript代码操纵HTTP是可行的。
1) HTTP请求组成
HTTP请求方法或动作
正在请求的URL
请求头集合,其中可能包含身份验证信息(可选)
请求体(可选)
2) HTTP响应
一个数字和文本组成的返回码,用来显示请求的成功和失败
一个响应头集合
响应体
3. XMLHttpRequest
浏览器在XMLHttpRequest类上定义了它们的HTTP API,这个类的每个实例都表示一个独立的请求/响应对,并且这个对象的属性和方法允许指定请求细节和提取响应数据。很多年前Web浏览器就开始支持XMLHttpRequest,并且其API已经到了W3C指定标准的最后阶段。同时W3C正在指定“2级XMLHttpRequest”标准草案。
在使用XMLHttpRequest时,必须将html部署到web服务器中。
1) 指定请求
1. 实例化
var request = new XMLHttpRequest();
request为实例化的XMLHttpRequest对象,该对象可以重用,但是这将会终止之前通过该对象挂起的任何请求。
2. 指定请求
open()
参数:
1.指定HTTP方法或动作,这个字符串不区分大小写,通常大家用大写字母来匹配HTTP协议。取值可以为:GET/POST/HEAD/DELETE/OPTIONS/PUT
GET :用于常规请求,适用于URL完全指定的请求资源,请求对服务器没有任何副作用,服务器的响应是(可缓存)的
POST:用于HTML表单,它在请求主体中包含额外数据,且这些数据常存储到服务器上的数据库中。相同URL的重复POST请求从服务器得到的响应可能不同,同时(不应该缓)存使用这个方法的请求。
2.URL,请求的主题,是相对于文档的URL。跨域请求会报错。
3.Boolean类型的值,如果值为false代表同步请求,send()方法将阻塞直到请求完成。这种情况下无需使用事件处理函程序,一旦send()返回,只需检查XMLHttpRequest对象的status和responseText属性。
request.open("GET","data.xml");
3. 设定请求头
setRequestHeader();
如果有请求头,需要调用该方法进行设定。
参数:
1.key
2.value
request.setRequestHeader("Content-type","text/plain;charset=UTF-8");
//json数据格式
request.setRequestHeader("Content-Type","application/json");
注意:
XMLHttpRequest将自动添加以下这些请求头以防止伪造,我们无法向setRequestHeader()传递以下请求头。
Accept-Charset TE Content-Transfer-Encoding
Accept-Encoding Date Trailer
Connection Expect Transfer-Encoding
Content-Length Host Upgrade
Cookie Keep-Alive User-Agent
Cookie2 Referer Via
4. 指定可选的请求主体并向服务器发送
send()
参数:
请求主体内容,如果没有,为null,或者省略。
/*
使用POST方法提交纯文本给服务器
*/
function postMessage(url,msg){
var request = new XMLHttpRequest();
request.open("POST",url);
request.setRequestHeader("Content-type","text/plain;charset=UTF-8");
request.send(msg);
}
2) 取得响应 (request属性)
HTTP状态码
status 以数字number形式返回HTTP状态码 200(ok) 404 服务器找不到 403 跨域访问报错
500 后台代码异常
statusText 以文本string形式返回HTTP状态码 OK Not Found
getResponseHeader() 获取指定响应头
getAllResponseHeaders() 获取所有响应头
responseText 获取文本形式(string)的响应体
responseXML 获取Document形式的响应体
JS状态码
readyState 返回HTTP请求状态
0 open()尚未调用 UNSENT 还未发货
1 open()已调用 OPENED 已经发货
2 接收到头信息 HEADERS_RECEIVED 货到了
3 接收到响应主体 LOADING 确认收货
4 响应完成 DONE 订单完成
【请求完成后激发的事件】
onreadystatechange 请求状态改变事件
当readyState值改变为4或服务器的响应完成时,所有的浏览器都触发该事件
/*
获取HTTP响应
*/
function getText(url,callback){
//1.实例化XMLHttpRequest
var request = new XMLHttpRequest();
//2.指定请求
request.open("GET",url);
request.onreadystatechange = function(){
//如果请求完成,并且请求成功
if(request.readyState === 4 && request.status ===200){
//3.设定请求头
var type = request.getResponseHeader("Content-type");
if(type.match(/^text/)){ //如果响应是文本
callback(request.responseText);//执行回调函数
}
}
};
//4.发送请求
request.send(null);
}
3) 响应解码
1.MIME类型为text/plain,text/html,text/css 文本类型时,可以使用responseText属性解析
2.MIME类型为XML文档类型时,使用responseXML属性解析
3.如果服务器发送对象,数组这样的结构化数据作为其响应,他应该传输JSON编码的字符串数据。通过responseText接受到它,可以把它传递给JSON.parse()方法来解析。
4.编码请求主体
HTTP POST请求包括一个请求主体,它包含客户端传递给服务器的数据。
1) 表单编码的请求
当用户提交表单时,表单中的数据(每个表单元素的名字和值)编码到一个字符串中并随请求发送。对表单数据的编码方案:对每个表单元素的名字和值执行普通的URL编码(使用十六进制转义码替换特殊字符),使用等号把编码后的名字和值分开,并使用"&"符号分开键/值对。表单数据编码格式有一个正式的MIME类型 application/x-www-form-urlencoded(默认)
当使用POST方式提交这种顺序的表单时,必须设置"Content-Type"请求头为"application/x-www-form-urlencoded"用于HTTP请求的编码对象
编码表单数据(封装)
function encodeFormData(data){
if(!data){
return "";
}
var pairs = [];
for(var name in data){
if(!data.hasOwnProperty(name)){
continue;
}
if(typeof data[name] == "function"){
continue;
}
var value = data[name].toString();
name = encodeURIComponent(name).replace("%20","+");//编码名字
value = encodeURIComponent(value).replace("%20","+");//编码值
pairs.push(name+"="+value);
}
return pairs.join('&');
}
name=%E6%9D%8E%E6%98%A5%E9%9B%A8+terry&passwd=110
使用表单编码数据发起一个HTTP POST请求
function postData(url,data,callback){
var request = new XMLHttpRequest();
request.open("POST",url);
reqeust.onreadystatechange = function(){
if(request.readyState === 4 && callback){
callback(request);
}
};
//设置请求头
request.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
//发送表单编码的数据
request.send(encodeFormData(data));
}
使用表单编码数据发起GET 请求
function getData(url,data,callback){
var request = new XMLHttpRequest();
request.open("GET",url+"?"+encodeFormData(data));
reqeust.onreadystatechange = function(){
if(request.readyState === 4 && callback){
callback(request);
}
};
request.send(null);
}
2) JSON格式的编码请求
/*
对象序列化
对象序列化是指将对象的状态转换为字符串,也可以反序列化,将字符串还原为对象函数,RegExp,Error对象,undefined值不能序列化和反序列化。
JSON.stringify(obj)
将对象序列化为Json字符串,只能序列化对象可枚举的自有属性。
JSON.parse(jsonStr)
反序列化 将字符串解析为对象
*/
近年来,作为Web交换格式的JSON已经得到了普及。
function postJSON(url,data,callback){
var request = new XMLHttpRequest();
request.open("POST",url);
reqeust.onreadystatechange = function(){
if(request.readyState === 4 && callback){
callback(request);
}
};
request.setRequestHeader("Content-Type","application/json");
request.send(JSON.stringify(data));
}
3) XML编码的请求
XML有时也用于数据传输的编码,但是较少
//doc表示一个XML DOM
function postXML(url,doc,callback){
var request = new XMLHttpRequest();
request.open("POST",url);
reqeust.onreadystatechange = function(){
if(request.readyState === 4 && callback){
//var text = request.responseText;
var result = responseXML;
callback(result);
}
};
//自动设置合适的头部。
request.send(doc);
}
5. 中止请求和超时
function getData(url,timeout,callback){
var request = new XMLHttpRequest();
var flag = false;
var timer = setTimeout(function(){
flag = true;
request.abort();//中止请求
},timeout);
request.open("GET",url+"?"+encodeFormData(data));
reqeust.onreadystatechange = function(){
if(request.readyState !== 4 ){
return;
}
if(timeout){
return; //如果超时返回
}else{
clearTimeout(timmer);
}
if(request.status === 200){
callback(request);
}
};
request.send(null);
}
6. 跨域HTTP请求
作为同源策略的一部分,XMLHttpRequest对象通常仅可以发起和文档具有相同服务器的HTTP请求。可以在<form>
,<iframe>元素中使用跨域URL,但因为同源策略,浏览器不允许原始脚本查找跨域文档内容。
不过我们又发现,Web页面上调用js文件时则不受是否跨域的影响
(不仅如此,我们还发现凡是拥有”src”这个属性的标签都拥有跨域的能力,比如<script>、<img>、<iframe>。
1) JSONP --json padding
为了便于客户端使用数据,逐渐形成了一种非正式传输协议,人们把它称作JSONP,该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
1. js跨域访问
远程服务器下 文件remote.js
alert('我是远程文件');
本地服务器下 文件jsonp.html
<script type="text/javascript" src="http://otherHost/remote.js"></script>
这时候会alert,说明跨域访问调用成功
2. 远程调用本地代码
远程服务器下 文件remote.js
localHandler({"result":"我是远程js带来的数据"});
本地服务器下 文件jsonp.html
var localHandler = function(data){
alert('我是本地函数,可以被跨域的remote.js文件调用,远程js带来的数据是:' + data.result);
};
<script type="text/javascript" src="http://otherHost/remote.js"></script>
3. 动态调用
远程服务器下 文件remote.js
flightHandler({
"code": "CA1998",
"price": 1780,
"tickets": 5
});
本地服务器下 文件jsonp.html
// 得到航班信息查询结果后的回调函数
var flightHandler = function(data){
try{
alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 张。');
}finally{
script.parentNode.removeChild(script);
}
};
// 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码)
//调用的url中传递了一个code参数,告诉服务器我要查的是CA1998次航班的信息,而callback参数则告诉服务器,我的本地回调函数叫做flightHandler,所以请把查询结果传入这个函数中进行调用。
var url = "jsonp.js?code=CA1998&callback=flightHandler";
// 创建script标签,设置其属性
var script = document.createElement('script');
script.setAttribute('src', url);
// 把script标签加入head,此时调用开始
document.getElementsByTagName('head')[0].appendChild(script);
4. 封装
getJSONP.counter = 0;//回调函数名称计数器
function getJSONP(url,callback){
var cbnum = "cb"+getJSONP.counter++;
var cbname = "getJSONP."+cbnum;
if(url.indexOf("?") === -1){
url += "?jsonp="+cbname;
}else{
url += "&jsonp="+cbname;
}
var script = document.createElement("script");
//为每个请求创建了一个全新的内部回调函数,作为getJSON函数的一个属性储存。
getJSONP[cbnum]= function(response){
try{
callback(response);
}finally{
//清理工作:删除回调函数
delete getJSONP[cbnum];移除script元素
script.parentNode.removeChild(script);
}
}
}
//调用
getJSONP("getAllStudents.action?clazz=1",function(response){
//处理
...
});
2) CORS(跨域资源共享,Cross-Origin Resource Sharing)
CORS是W3C的一个工作草案,定义了在必须访问跨域资源时,浏览器和服务器应该怎么沟通,CORS背后的思想是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应应该是成功还是失败
例如:
当前域为 http://www.briup.com
如果远程服务器认为这个请求可以接受,就在Access-Control-Allow-Origin头部中回发相同的信息
Access-Control-Allow-Origin:http://www.briup.com
如果没有这个头部,或者有这个头部但源信息不匹配,浏览器会驳回请求。
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。
实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
3.Cookie
CORS请求默认不发送Cookie和HTTP认证信息。如果要把Cookie发到服务器,一方面要服务器同意,指定Access-Control-Allow-Credentials字段。
Access-Control-Allow-Credentials: true;
另一方面,开发者必须在AJAX请求中打开withCredentials属性。
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
需要注意的是,如果要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名。同时,Cookie依然遵循同源政策,只有用服务器域名设置的Cookie才会上传,其他域名的Cookie并不会上传,且(跨源)原网页代码中的document.cookie也无法读取服务器域名下的Cookie。
附:
1. JSON
JSON能够以非常简单的方式来描述数据结构,XML能做的它都能做,因此在跨平台方面两者完全不分伯仲。以下是JSON规则:
1) JSON只有两种数据类型描述符,大括号{}和方括号[]其余英文冒号:是映射符,英文逗号,是分隔符,英文双引号”“是定义符。
2) 大括号{}用来描述一组“不同类型的无序键值对集合”(每个键值对可以理解为OOP的属性描述),方括号[]用来描述一组“相同类型的有序数据集合”(可对应OOP的数组)。
3) 上述两种集合中若有多个子项,则通过英文逗号,进行分隔。
4) 键值对以英文冒号:进行分隔,并且建议键名都加上英文双引号””,以便于不同语言的解析。
5) JSON内部常用数据类型无非就是字符串、数字、布尔、日期、null 这么几个,字符串必须用双引号引起来,其余的都不用,日期类型比较特殊,这里就不展开讲述了,只是建议如果客户端没有按日期排序功能需求的话,那么把日期时间直接作为字符串传递就好,可以省去很多麻烦。
2. 编码方式
encodeURI 和 encodeURIComponent都是ECMA-262标准中定义的函数,所有兼容这个标准的语言(如JavaScript, ActionScript)都会实现这两个函数。它们都是用来对URI (RFC-2396)字符串进行编码的全局函数,但是它们的处理方式和使用场景有所不同。为了解释它们的不同,我们首先需要理解RFC-2396中对于URI中的字符分类
1) 保留字符(reserved characters):这类字符是URI中的保留关键字符,它们用于分割URI中的各个部分。这些字符是:”;” “/” “?” “:” “@” “&” “=” “+” “$” “,”
2) Mark字符(mark characters):这类字符在RFC-2396中特别定义,但是没有特别说明用途,可能是和别的RFC标准相关。 这些字符是:”-” “_” “.” “!” “~” “*” “’” “(” “)”
3) 基本字符(alphanum characters):这类字符是URI中的主体部分,它包括所有的大写字母、小写字母和数字
在介绍完上面三类字符串后,我们就非常容易来解释encodeURI和encodeURIComponent函数的不同之处了:
1) encodeURI: 该函数对传入字符串中的所有非(基本字符、Mark字符和保留字符)进行转义编码(escaping)。所有的需要转义的字符都按照UTF-8编码转化成为一个、两个或者三个字节的十六进制转义字符(%xx)。例如,字符空格" "转换成为"%20"。在这种编码模式下面,需要编码的ASCII字符用一个字节转义字符代替,在\u0080和\u007ff之间的字符用两个字节转义字符代替,其他16为Unicode字符用三个字节转义字符代替
2) encodeURIComponent: 该函数处理方式和encodeURI只有一个不同点,那就是对于保留字符同样做转义编码。例如,字符":"被转义字符"%3A"代替
之所以有上面两个不同的函数,是因为我们在写JS代码的时候对URI进行两种不同的编码处理需求。encodeURI可以用来对完整的URI字符串进行编码处理。而encodeURIComponent可以对URI中一个部分进行编码,从而让这一部分可以包含一些URI保留字符。这在我们日常编程中是十分有用的。比如下面的URI字符串:
http://www.mysite.com/send-to-friend.aspx?url=http://www.mysite.com/product.html
在这个URI字符串中。send-to-friend.aspx页面会创建HTML格式的邮件内容,里面会包含一个链接,这个链接的地址就是上面URI字符串中的url值。显然上面的url值是URI中的一个部分,里面包含了URI保留关键字符。我们必须调用encodeURIComponent对它进行编码后使用,否则上面的URI字符串会被浏览器认为是一个无效的URI。正确的URI应该如下:
http://www.mysite.com/send-to-friend.aspx?url=http%3A%2F%2Fwww.mysite.com%2Fproduct.html
GET请求(明信片)
a.html -> b.html
携带参数:
a.html?key1=val1&key2=val2浏览器地址栏:
getAllStudents.action?clazz=三年二班&gender=男POST提交(信)
a.html -> b.html
浏览器地址栏:
getAllStudents.action
参数: 保存在请求体中。
*****************回顾+note*************************
DOM
Node
document element
事件
事件流
事件绑定方法
DOM0
DOM2
事件类型
支持子元素
click
mouseover
mouseout
事件代理
递归
5!
function fac(num){
if(num<=1){
return 1;
}else{
return num*arguments.callee(num-1);
}
}
fac(4);
上面的方式在严格模式下不能使用
fac = function f(num){
if(num<=1){
return 1;
}else{
return num*f(num-1);
}
};
闭包
例1
var a = 3;
a = 4;
function showA(){
alert(a);// alert(scope.a);
}
a = 5;
showA();
showA闭包= {
showA
scope = {a:5}
}
例2
function
<ul>
<li>test1</li>
<li>test2</li>
<li>test3</li>
</ul>
var lis = document.getElementsByTagName(li);
for(var i=0;i<lis.length;i++){
lis[i].onclick = function(){
lis[i].innerHTML = "dom"+(i+1);
};
}
//解决
for(var i=0;i<lis.length;i++){
lis[i].onclick =(function(num){
//函数调用 i被解析
return function(){
lis[num].innerHTML = "dom"+(num+1);
};
})(i);
}
//forEach
将类数组转换数组对象
BOM
JS是单线程语言
超时调用
函数,在一定时间之后才去执行
setTimeout()
参数
要调用的函数
超时时间
间歇调用
setInterval();
参数
要调用的函数
间歇时间
函数执行
局部变量
var a = 1; //全局变量
function foo(){
alert(a);
var b = 2; //局部变量
if(a>0){
var c = 3;//块级变量
}
alert(c);
//只要在函数内部声明的变量,在声明之后都可以放到
}
alert(b);//访问不到
Ajax
服务器
Apache
htdocs 服务器根目标
项目的部署
javascript/ajax.html
bin 启动或关闭服务器
将Apache服务器打开 80
在浏览器中访问呢
http://127.0.0.1:80/javascript/ajax.html
http://127.0.0.1:80/
---> htdocs/ 服务器根目录
http://127.0.0.1:80/javascript/ajax.html
htdocs/javascript/ajax.html
ajax.html
data.json
路径
相对路径
路径不以”/”开头
request.open(“GET”,”data.json”);
相对于当前文件所在目录
当前文件 ajax.html-> http://127.0.0.1:80/javascript/
http://127.0.0.1:80/javascript/data.json
绝对路径
路径以"/"开头
request.open("GET","/data.json");
相对于服务器根目录
htdocs-> http://127.0.0.1:80/
http://127.0.0.1:80/data.json
http://172.16.20.87/javascript/day13_ajax/ajax_basic.html
******************Ajax-2-note*****************
1. Ajax
异步的JavaScript 和 XML
JSON
浏览器与服务器之间的数据交互
前端后台交互
XMLHttpRequest
XHR
1)发送请求
var request = new XMLHttpRequest();
request.open(“GET”,”a.json”);
request.setRequestHeader(“Content-type”,”text/plain”);
request.send(); //null
2)获取响应
status HTTP状态码
200
404
403 跨域访问
500 后台代码异常
statusText HTTP状态文本
OK
Not FoundreadyState 状态码 0 1 open() 2 服务器接收到请求头 3 浏览器接收到响应头 4 响应完成 onreadystatechange responseText 响应文本 responseXML Document
web服务器
Apache
bin 可执行文件
conf 配置文件 httpd.conf
htdocs 服务器根目
–
WebUI/pages 服务器根目标
Apache使用
1) 启动服务器
2) 测试 http://127.0.0.1:80
3) 代码部署
DW站点 -> htdocs
newBalance/*.html
4) 访问项目
http://127.0.0.1:80/newBalance/index.html
http://127.0.0.1:80/newBalance/a.jpg<img src="/a.jpg" alt=""> http://127.0.0.1:80/a.jpg
路径
相对路径
不以/开头,相对于当前文件所在的目录绝对路径 以/开头,/代表项目的根目录 [文件相对于服务器下的项目文件] http://127.0.0.1:80/ htdocs
封装getTextData,getXMLData
- 解析了xml数据
loadDom
$.load();name=%E6%9D%8E%E6%98%A5%E9%9B%A8+terry&passwd=110
name=%E6%9D%8E%E6%98%A5%E9%9B%A8+terry&passwd=110
- 通过ajax模拟form表单的提交
enctype取值 application/x-www-form-urlencoded(默认)
二进制(分段上传) multipart/form-data (有图片时一定要)
text/plain;
1)form表单怎么提交数据
obj={
name :"大大大 terry",
passwd : "123"
}
编码:
enctype="application/x-www-form-urlencoded"
提交时候值得样子
name=%E6%9D%8E%E6%98%A5%E9%9B%A8+terry&passwd=110
编码函数
encodeFormData(obj){
}
2) JSON
obj={
name :"大大大 terry",
passwd : "123"
}
提交时候的样子
{"name":"大大大 terry","passwd":"123"}
这是一个例子:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>AJAX</title>
<style>
table{width:400px; border-collapse:collapse;}
table td,th{border:1px solid #ccc;}
</style>
<script type="text/jscript">
window.onload = function(){
var btns = document.getElementsByTagName("button");
var tbls = document.getElementsByTagName("tbody");
//处理数据
function handlerData(data){
//反序列化 将字符串解析为对象
var stus = JSON.parse(data);
//遍历删除tbody中所有的子元素
Array.prototype.slice.call(tbls[0].children,0).forEach(
function(item){
tbls[0].removeChild(item);
});
//stus纯数组直接用forEach遍历出数组元素
stus.forEach(function(stu){
//每遍历出一个学生创建一个tr
//{ id,name,age,gender} 遍历出来的是一个学生对象
var newTr = document.createElement("tr");
//每个学生继续遍历其属性 因为每个学生当中的属性占一个td
for( var key in stu){
//每遍历一个属性创建一个td
var newTd = document.createElement("td");
//把属性的值(内容)拿出来放入td当中
newTd.innerHTML = stu[key]; //属性值 innerText
//把td追加到tr
newTr.appendChild(newTd);
}
tbls[0].appendChild(newTr);
});
}
//点击get请求按钮,像服务器发送请求
btns[0].onclick = function(){
//ajax
//1 实例化XMLHttpReuquest
var request = new XMLHttpRequest();
//2 指定请求
request.open("GET","data.json"); //后期-服务器技术-"getAllstudents.action?class =1"
//加斜杠为服务器的根目录 绝对路径
//3 设定请求头
request.setRequestHeader("Content-type","text/plain;charset=UTF-8");
//4 发送请求头
request.send();
//处理响应
//绑定一个on事件 监听请求完成,然后处理数据
request.onreadystatechange = function(){
console.log(request.readyState); //2,3,4
if(request.readyState === 4 && request.status ===200){
//获取到响应的文本数据
var text = request.responseText; //获取到字符串类型的json 打印在控制台的字符串
console.log(text);
handlerData(text); //回调
//var stus = JSON.parse(text);
//反序列化 将字符串解析为对象
// var stus = JSON.stringify(text);
//console.log(stus);
}
};
};
};
</script>
</head>
<body>
<h1>从服务器上请求 的html文件</h1>
<button>get请求</button>
<table>
<thead>
<tr>
<th>学号</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</body>
</html>