Ajax
客户端与服务器
服务器:负责存放和对外提供资源的电脑
客户端:负责获取和消费资源的电脑
URL地址:统一资源定位符(看作身份证号),表示互联网上每一个资源的唯一存放位置
由三部分组成
- 通信协议
- 服务器名称
- 具体的存放位置
客户端与服务器的 通信过程:请求-处理-响应
在网页中请求服务器上的数据资源,需要使用XMLHttpRequest对象
用法:var xhrObj=new XMLHttpRequest()
常见的两种请求方式
get请求用于获取服务器资源
例如获取图片,音频等
post请求常用语向服务器提交数据
例如:登陆、注册等
Ajax可以实现网页与服务器之间的数据交互
应用场景:
用户名检测:注册时,通过ajax形式,动态监测用户名是否被占用。
搜索提示:当输入关键字,通过ajax形式,动态提供列表。
数据的增删改查,实现数据的交互
$.get()函数
<button id="btnGET">发起不带参数的Get请求</button>
<script>
$(function () {
$("#btnGET").on("click", function () {
$.get('http://www.liulongbin.top:3006/api/getbooks', function (res) {
console.log(res);
})
})
})
</script>
通过XHR页签监听请求
<button id="btnGET">发起带参数的Get请求</button>
<script>
$(function () {
$("#btnGET").on("click", function () {
$.get('http://www.liulongbin.top:3006/api/getbooks', { id: 2 }, function (res) {
console.log(res);
})
})
})
</script>
$.post()函数
<button id="btnPOST">发起post请求</button>
<script>
$(function () {
$("#btnPOST").on("click", function () {
$.post("http://www.liulongbin.top:3006/api/addbook", {
bookname: '活出生命的意义',
author: '美国人',
publisher: '天津出版社'
}, function (res) {
console.log(res);
})
})
})
</script>
$.ajax()函数
功能综合
使用$.ajax()发起get请求
<button id="btnGET">发起get请求</button>
<script>
$(function () {
$("#btnGET").on("click", function () {
$.ajax({
type: 'GET',
url: 'http://www.liulongbin.top:3006/api/getbooks',
data: {
id: 1
},
success: function (res) {
console.log(res);
}
})
})
})
</script>
使用$.ajax()发起post请求
<button id="btnPOST">发起post请求</button>
<script>
$(function () {
$("#btnPOST").on("click", function () {
$.ajax({
type: 'POST',
url: 'http://www.liulongbin.top:3006/api/addbook',
data: {
bookname: '活出生命的意义',
author: '美国人',
publisher: '天津出版社'
},
success: function (res) {
console.log(res);
}
})
})
})
</script>
接口
使用ajax请求数据时,被请求的URL地址,就叫做数据接口,同时每个接口必须有请求方式。
获取图书的接口:http://www.liulongbin.top:3006/api/getbooks
添加图书的接口:http://www.liulongbin.top:3006/api/addbook
Postman测试接口过程
- 选择请求方式
- 填写请求的URL地址
- 填写请求的参数
- 点击Send按钮发起GET请求
- 查看服务器相应的结果

Postman测试POST接口
步骤:
- 选择请求的方式
- 填写请求的URL地址
- 选择Body面板并勾选数据格式
- 填写要发送到服务器的数据
- 点击Send按钮发起POST请求
- 查看服务器响应的结果

接口文档
接口的说明文档,它是我们调用接口的依据,好的接口文档包含了对接口URL,参数以及输出内容的说明,我们参照接口就能方便的知道接口的作用,以及接口如何进调用。
接口文档的组成部分
接口名称:标识接口
接口URL:接口调用地址
调用方式:如get和post
参数格式:接口需压迫传递的参数,每个参数必须包括参数名称、参数类型、是否必选、参数说明这四项内容
响应格式:接口的返回值的详细描述,一般包含数据名称、数据类型、说明
返回事例(可选):通过对象的形式,例举返回数据的结构
案例:图书的增删改查
<link rel="stylesheet" href="bootstrap.min.css">
<script src="jquery.min.js"></script>
<body style="padding: 15px;">
<!-- //添加图书的panel面板 -->
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">添加新图书</h3>
</div>
<div class="panel-body form-inline">
<div class="input-group">
<div class="input-group-addon">书名</div>
<input type="text" class="form-control" id="iptBookname" placeholder="请输入书名">
</div>
<div class="input-group">
<div class="input-group-addon">作者</div>
<input type="text" class="form-control" id="iptAuthor" placeholder="请输入作者">
</div>
<div class="input-group">
<div class="input-group-addon">出版社</div>
<input type="text" class="form-control" id="iptpublisher" placeholder="请输入出版社">
</div>
<button id="btnAdd" class="btn btn-primary">添加</button>
</div>
</div>
<!-- 图书的表格 -->
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>ID</th>
<th>书名</th>
<th>作者</th>
<th>出版社</th>
<th>操作</th>
</tr>
</thead>
<tbody id="tb">
</tbody>
</table>
<script>
$(function () {
//获取图书列表的数据
function getBookList() {
$.get("http://www.liulongbin.top:3006/api/getbooks", function (res) {
// console.log(res);
if (res.status !== 200) return alert("获取数据失败");
var rows = [];
$.each(res.data, function (i, item) {
rows.push("<tr><td>" + item.id + "</td><td>"
+ item.bookname + "</td><td>" + item.author +
"</td><td>" + item.publisher +
"</td ><td><a href='javascript:;' class='del' data-id='" + item.id + "'>删除</a></td></tr > ");
})
$("#tb").empty().append(rows.join(''));
})
}
getBookList();
$("tbody").on("click", ".del", function () {
var id = $(this).attr("data-id");
$.get('http://www.liulongbin.top:3006/api/delbook', { id: id }, function (res) {
if (res.status !== 200) return alert("删除失败!");
getBookList();
});
})
$("#btnAdd").on("click", function () {
var bookname = $("#iptBookname").val().trim();
var author = $("#iptAuthor").val().trim();
var publisher = $("#iptpublisher").val().trim();
if (bookname.length <= 0 || author.length <= 0 || publisher.length <= 0) {
return alert('请填写完整的图书信息!');
};
$.post("http://www.liulongbin.top:3006/api/addbook",
{
bookname: bookname, author: author, publisher: publisher
}, function (res) {
if (res.status !== 201) { return alert("添加错误") }
getBookList();
$("#iptBookname").val('');
$("#iptAuthor").val('');
$("#iptpublisher").val('');
});
})
})
</script>
</body>
form表单
在网页中负责数据采集,HTML中form标签,用于采集用户输入的信息,并通过form标签提交操作,把采集到的信息提交到服务器端处理。
action属性:规定当提交表单时,提交的地址.
当form表单未指定URL,那么则将数据提交到当前页面的URL
也可以理解action的默认值为当前页面的URL
target属性:规定在何处打开action URL
一般情况下给target设置两种值:
_blank :在新窗口中打开
_self:默认在相同的框架中打开
method属性:规定以何种方式把表单提交到action URL
可选值为get和post
默认情况的值为get
enctype属性:规定在发送表单之前如何对数据进行编码
默认情况下值:application/x-www-form-urlencoded
如果涉及文件上传,必须要将enctype值设置为:multipart/form-data
表单的同步提交
通过点击submit按钮,触发表单提交的操作,从而使页面跳转到action URL的行为,叫做表单的同步提交。
缺点:
- 页面跳转
- 页面之前的状态和数据会丢失
采用ajax将数据提交到服务器,表单值负责采集数据
监听表单提交事件
两种方法
<form id="f1" action="/login" target="_blank" method="post">
<input type="text" name="email_or_mobile" />
<input type="password" name="password" />
<button type="submit">提交</button>
</form>
<script>
$(function () {
//one
// $("#f1").submit(function () {
// alert("监听到表单提交");
// })
//two
$("#f1").on("submit", function () {
alert("监听到表单提交");
})
})
</script>
阻止表单默认行为
当监听到表单的提交事件后,可以 调用事件对象的event.preventDefault()函数,来阻止表单的提交和页面的跳转。
//阻止表单的默认提交行为 //one // $("#f1").submit(function (e) { // e.preventDefault(); // }); //two $("#f1").on("submit", function (e) { e.preventDefault(); })
快速获取表单中的数据
//快速获取表单的值 //one $("#f1").submit(function (e) { e.preventDefault(); var data = $(this).serialize(); console.log(data); });
案例:评论发表
<body style="padding: 15px;">
<!-- //1.评论面板 -->
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">发表评论</h3>
</div>
<form class="panel-body" id="formAddcmt">
<div>评论人:</div>
<input type="text" class="form-control" name="username" />
<div>评论内容:</div>
<textarea class="form-control" name="content"></textarea>
<button type="submit" class="btn btn-primary">发表评论</button>
</form>
</div>
<!-- //评论列表 -->
<ul class="list-group" id="cmt-list">
<li class="list-group-item">
<span class="badge" style="background-color:#f0ad4e;">评论时间</span>
<span class="badge" style="background-color: #5bc0de;">评论人</span>
Item 1
</li>
</ul>
<script>
function getComment() {
$.ajax({
method: 'GET',
url: 'http://www.liulongbin.top:3006/api/cmtlist',
data: {},
success: function (res) {
console.log(res);
if (res.status != 200) return alert('获取失败');
// console.log('success');
var rows = [];
$.each(res.data, function (i, item) {
var str = '<li class="list-group-item"><span class="badge" style="background-color:#f0ad4e;">评论时间' + item.time +
'</span><span class="badge" style="background-color: #5bc0de;">评论人'
+ item.username + '</span>' + item.content + '</li > ';
rows.push(str);
});
$("#cmt-list").empty().append(rows.join(''));
}
})
}
getComment();
$(function () {
$("#formAddcmt").submit(function (e) {
e.preventDefault();
var data = $(this).serialize();
$.post('http://www.liulongbin.top:3006/api/addcmt', data, function (res) {
if (res.status !== 201) {
return alert("发表评论失败");
}
getComment();
$("#formAddcmt")[0].reset();//转成原生的dom对象
})
})
})
</script>
</body>
模版引擎
可以根据程序员指定的模版结构和数据,自动生成一个完整的HTML页面
优点:
减少字符串的拼接操作
使代码结构更清晰
使代码更易于阅读与维护
art-template
简约、超快的模版引擎
<body>
<div id="container"></div>
<!-- 定义模版 -->
<script type="text/html" id="tpl">
<h1>{{name}}----{{age}}</h1>
<!-- //双花括号代表占位符 -->
</script>
<script>
// 定义需要渲染的数据
var data = { name: "ss", age: 20 };
//调用template函数
var str = template('tpl', data);
console.log(str);
//渲染html结构
$("#container").html(str);
</script>
</body>
Art-template标准语法
{{}}内可以进行变量输出、对象属性的输出、三元表达式的输出,逻辑或输出、加减乘除表达式的输出、过滤器
<div id="container"></div>
<!-- 定义模版 -->
<script type="text/html" id="tpl">
<h1>{{name}}----{{age}}</h1>
{{@test}}
<!-- //双花括号代表占位符 -->
<!-- 1.条件语句 -->
<div>
{{if flag===0 }}
flag的值是0
{{else if flag===1}}
flag的值是1
{{/if}}
</div>
<!--2. 循环输出 -->
<ul>
{{each hobby}}
<li>索引是:{{$index}}:{{$value}}</li>
{{/each}}
</ul>
<h3>{{regTime | dateFormat}}</h3>
</script>
<script>
//3.过滤器函数
template.defaults.imports.dateFormat = function (date) {
var y = date.getFullYear();
var m = date.getMonth() + 1;
return y + '-' + m;
}
// 定义需要渲染的数据
var data = {
name: "ss", age: 20, test: '<h3>测试原文输出</h3>', flag: 1, hobby: ['吃饭', '看书', '写代码']
, regTime: new Date()
};
//调用template函数
var str = template('tpl', data);
console.log(str);
//渲染html结构
$("#container").html(str);
</script>
正则与字符串操作
<script>
var str = '<div>我是{{name}}</div>';
var pattern = /{{([a-zA-Z]+)}}/;
var patternResult = pattern.exec(str);
console.log(patternResult);
</script>
replace函数
<script>
var str = '<div>我是{{name}}</div>';
var pattern = /{{([a-zA-Z]+)}}/;
var patternResult = pattern.exec(str);
str = str.replace(patternResult[0], patternResult[1]);
console.log(patternResult);
console.log(str);
</script>
多次replace操作
<script>
var str = '<div>我是{{name}}年龄{{age}}</div>';
var pattern = /{{\s*([a-zA-Z]+)\s*}}/;
var patternResult = pattern.exec(str);
//第一次替换
str = str.replace(patternResult[0], patternResult[1]);
console.log(patternResult);
console.log(str);
var patternResult = pattern.exec(str);
//第二次替换
str = str.replace(patternResult[0], patternResult[1]);
console.log(patternResult);
console.log(str);
</script>
换种思路:循环使用
var str = '<div>我是{{name}}年龄{{age}}</div>'; var pattern = /{{\s*([a-zA-Z]+)\s*}}/; //循环replace var patternResult = null; while (patternResult = pattern.exec(str)) { str = str.replace(patternResult[0], patternResult[1]); } console.log(str);
replace替换为真值
var data = { name: '张三', age: 20 }; var str = '<div>我是{{name}}年龄{{age}}</div>'; var pattern = /{{\s*([a-zA-Z]+)\s*}}/; //循环replace var patternResult = null; while (patternResult = pattern.exec(str)) { str = str.replace(patternResult[0], data[patternResult[1]]); } console.log(str);
调用自己的模版引擎
html文件
<div id="user-box"></div>
<script type="text/html" id="tpl">
<div>姓名:{{name}}</div>
<div>年龄:{{age}}</div>
<div>性别:{{gender}}</div>
<div>地址:{{address}}</div>
</script>
<script>
//定义数据
var data = {
name: '张三', age: 20, gender: '男',
address: 'shanghai'
};
//调用引擎模版
var htmlstr = template("tpl", data);
//渲染html结构
document.getElementById("user-box").innerHTML = htmlstr;
</script>
自己的template.js文件
function template(id, data) { var str = document.getElementById(id).innerHTML; var pattern = /{{\s*([a-zA-Z]+)\s*}}/; //循环replace var patternResult = null; while (patternResult = pattern.exec(str)) { str = str.replace(patternResult[0], data[patternResult[1]]); } return str; }
XMLHttpRequest的基本使用
可以请求服务器上的数据资源,ajax函数就是基于xhr对象封装出来的
<script>
//使用XHR进行get请求
//1.创建XHR对象
var xhr = new XMLHttpRequest();
//2.调用open函数
xhr.open("GET", "http://www.liulongbin.top:3006/api/getbooks");
//3.调用send函数
xhr.send();
//4.监听
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
//获取响应结果
console.log(xhr.responseText);
}
}
</script>
带参数的get请求
xhr.open("GET", "http://www.liulongbin.top:3006/api/getbooks?id=1");
如何对URL进行编码和解码
<script>
var str = '黑马程序员';
//编码
var str2 = encodeURI(str);
console.log(str2);
//解码
var str3 = decodeURI(str2);
console.log(str3);
</script>
使用XHR进行POST请求
//使用XHR进行post请求 //1.创建XHR对象 var xhr = new XMLHttpRequest(); //2.调用open函数 xhr.open("POST", "http://www.liulongbin.top:3006/api/addbook"); //3.设置content-type xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); //4.调用send函数 xhr.send('bookname=水浒传&author=施耐庵&publisher=上海版社'); //5.监听 xhr.onreadystatechange = function () { if (xhr.readyState == 4 && xhr.status == 200) { //获取响应结果 console.log(xhr.responseText); } }
数据交换格式
服务器端与客户端进行数据传输与交换的格式
主要使用JSON 和 XML
XML:可扩展标记语言
- HTM L是用来描述网页上的内容,是网页内容的载体
- XML是用来传输和存储数据,是数据的载体
缺点:格式复杂,和数据无关的代码多,体积大,传输效率低,在js中解析XML比较麻烦。
JSON:js对象和数组的字符串表示法,一种轻量级的文本数据交换格式,主流交换格式。
JSON的两种结构
对象结构和数组结构,字符串用双引号,数据类型可以是数字、字符串、布尔值、null、数组、对象
JSON的作用:在计算机与网络之间存储和传输数据
JSON的本质:用字符串来表示js对象数据和数组数据
JSON和JS对象的互转
//JSON-->JS var jsonStr = '{"a":"hello","b":"hi"}'; var jsStr = JSON.parse(jsonStr); console.log(jsStr); //JS-->JSON var jsStr = { a: 'hello', b: 'hi' }; var jsonStr = JSON.stringify(jsStr); console.log(jsonStr); //应用场景 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 result = JSON.parse(xhr.responseText); console.log(result); } }
序列化和反序列化
把数据对象转换为字符串的过程叫做序列化,
把字符串转换为数据对象的过程叫做反序列化,
封装自己的Ajax函数
处理data参数:需要把data对象,转化成查询字符串的格式,从而提交给服务器,因此提前定义resolve Data函数如下:
function resolveData(data) { var arr = []; for (var k in data) { var str = k + '=' + data[k]; arr.push(str); } return arr.join("&") } // var res = resolveData({ name: "ss", age: 20 }); // console.log(res); function itheima(options) { var xhr = new XMLHttpRequest(); //把外界传递过来的参数对象转换为查询字符串 var qs = resolveData(options.data); if (options.method.toUpperCase() == 'GET') { //发起get请求 xhr.open(options.method, options.url + '?' + qs); xhr.send(); } else if (options.method.toUpperCase() == 'POST') { //发起post请求 xhr.open(options.method, options.url); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencode'); xhr.send(qs); } xhr.onreadystatechange = function () { if (xhr.readyState == 4 && xhr.status == 200) { var result = JSON.parse(xhr.responseText); options.success(result); } } }
测试
<script>
// //测试get
// itheima({
// method: 'GET',
// url: 'http://www.liulongbin.top:3006/api/getbooks',
// data: {
// id: 1
// },
// success: function (res) {
// console.log(res);
// }
// })
//测试post
itheima({
method: 'POST',
url: 'http://www.liulongbin.top:3006/api/addbook',
data: {
bookname: '水浒传',
author: '施耐庵',
publisher: '上海出版社'
},
success: function (res) {
console.log(res);
}
})
</script>
XMLHttpRequest level2的新特性
1.设置HTTP请求时限
<script>
var xhr = new XMLHttpRequest();
//设置超时函数
xhr.timeout = 3;
//设置超时后的处理函数
xhr.ontimeout = function () {
console.log('请求超时');
}
// 1.创建XHR对象
var xhr = new XMLHttpRequest();
//2.调用open函数
xhr.open("GET", "http://www.liulongbin.top:3006/api/getbooks?id=1");
//3.调用send函数
xhr.send();
//4.监听
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
//获取响应结果
console.log(xhr.responseText);
}
}
</script>
使用Form Data对象管理表单数据
<script>
//1.创建formdata实例
var fd = new FormData();
//2.调用append函数 向fd中追加数据
fd.append('uname', 'ss');
fd.append('upwd', '123456');
var 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(xhr.responseText);
}
}
</script>
获取网页表单的值
<form id="form1">
<input type="text" name="uname" autocomplete="off" />
<input type="password" name="upwd" />
<button type="submit"></button>
</form>
<script>
var form = document.querySelector("#form1");
form.addEventListener('submit', function (e) {
e.preventdefault();
//1.创建formdata实例
var fd = new FormData();
var xhr = new XMLHttpRequest();
xhr.open('GET', '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));
}
}
})
axios
专注于网络数据请求的库,只专注于网络数据请求
使用axios发送get请求
<button id="btn1">发起get请求</button>
<script>
document.querySelector("#btn1").addEventListener("click", function () {
var url = "http://liulongbin.top:3306/api/get";
var paramsobj = { name: 'ss', age: 20 }
axios.get(url, { params: paramsobj })
.then(function (res) {
console.log(res);
})
})
</script>
使用axios发送post请求
<button id="btn2">发起post请求</button>
<script>
document.querySelector("#btn2").addEventListener("click", function () {
var url = "http://liulongbin.top:3306/api/post";
var dataobj = { address: '上海', location: '浦东' };
axios.post(url, { params: dataobj })
.then(function (res) {
console.log(res.data);
})
})
</script>
直接使用axios发送get请求
<button id="btn3">直接发起get请求</button>
<script>
document.querySelector("#btn3").addEventListener("click", function () {
var url = "http://liulongbin.top:3306/api/get";
var paramsobj = { name: 'ss', age: 20 };
axios({
method: 'get',
url: url,
params: paramsobj
}).then(function (res) {
console.log(res.data);
})
})
</script>
直接使用axios发送post请求
<button id="btn4">直接发起post请求</button>
<script>
document.querySelector("#btn4").addEventListener("click", function () {
var url = "http://liulongbin.top:3306/api/post";
var dataobj = { name: 'ss', age: 20 };
axios({
method: 'post',
url: url,
data: dataobj
}).then(function (res) {
console.log(res.data);
})
})
</script>
同源
如果两个页面的协议和域名和端口都相同,则两个页面具有相同的源
同源策略
浏览器提供的一个安全功能
跨域
与同源相反的就是跨域
出现跨域的根本原因:浏览器不允许非同源的URL之间进行资源交互
注:浏览器允许发起跨域请求,但是,跨域请求回来的数据会被浏览器拦截,无法被页面获取到
实现跨域请求JSONP和CORS
JSONP:出现早,兼容性好,只支持get
CORS:出现晚,W3C标准,支持get和post,兼容性不好
JSONP
实现原理:通过script标签的src属性,请求跨域的数据接口,并通过函数调用的形式,接收跨域接口响应回来的数据。
<body>
<script>
function success(data) {
console.log('JSONP响应回来的数据是');
console.log(data);
}
</script>
<script src="http://ajax.frontend.itheima.net:3006/api/jsonp?callback=success&name=ls&age=30"></script>
</body>
jQuery中的JSONP
<script> $(function () { //发起JSONP的请求 $.ajax({ url: "http://ajax.frontend.itheima.net:3006/api/jsonp?name=ss&age=20", //代表我们发起JSONP的数据请求 dataType: 'jsonp', success: function (res) { console.log(res); } }) }) </script>
节流
指减少一段时间内事件的处罚频率
应用场景:当鼠标连续不断的触发某事件(如点击),只在单位时间内只触发一次;
懒加载要监听计算滚动条的位置,但不必每次滑动都触发,可以降低计算的频率,而不必浪费CPU的资源。
节流案例-鼠标跟随效果
节流阀:节流阀为空,表示可以执行下一次操作;不为空,表示不能执行下次操作。
当前操作操作执行完,必须将节流阀重置为空,表示可以执行下次操作了。
每次执行操作前,必须先判断节流是否为空。
<img src="cmq.JPG" id="cmq">
<script>
$(function () {
//不使用节流
//1.获取图片
var cmq = $('#cmq');
//(1)定义节流阀
var timer = null;
//2.绑定事件
$(document).on('mousemove', function (e) {
//(3)判断节流阀是否为空
if (timer) {
return
}
//(2)开启延时器
timer = setTimeout(function () {
$(cmq).css("top", e.pageY + 'px').css("left", e.pageX + 'px');
timer = null;
}, 16)
})
})
</script>
防抖:如果事件被频繁触发,防抖能保证只有一次出发生效,前面N多次的触发都会被忽略。
节流:如果事件被频繁触发,节流减少事件触发的频率,因此,节流是有选择性地执行一部分事件。
HTTP协议
客户端与服务器之间要实现网页内容的传输,则通信的双方必须遵守网页内容的传输协议,网页内容又叫做超文本,因此网页内容过的传输协议又叫做超文本传输协议
(hyper text transfer protocol)简称HTTP协议
HTTP协议采用请求/响应的交互模型
只有POST才有请求体,GET是没有请求体的
HTTP响应状态码
2**范围的状态码

3**范围的状态码

4**范围的状态码

5**范围的状态码


浙公网安备 33010602011771号