前后端通信
-
前后端通信 前端和后端数据交互的过程:浏览器和服务器之间数据交互的过程
-
后端向前端发送数据 访问页面
-
前端向后端发送数据 用户注册
- 前后端通信的过程与概念解释
- 前后端通信的过程 前后端的通信是在‘请求-响应’中完成的
- 概念解释
前端:浏览器端
客户端:只要能和服务器通信的就叫客户端
命令行工具 :curl https:www.imooc.com
后端:服务器端
- 前后端的通信方式 1. 使用浏览器访问网页 在浏览器地址栏输入网址,按下回车
2. HTML 的标签
浏览器在解析 HTML 标签的时候,遇到一些特殊的标签,会再次向服务器发送请求
link/img/script/iframe
还有一些标签,浏览器解析的时候,不会向服务器发送请求,但是用户可以使用他们向服务器发送请求
a/form
3. Ajax 和 Fetch
HTTP
初识HTTP
- HTTP 超文本传输协议
HTML:超文本标记语言
- 超文本:原先一个个单一的文本,通过超链接将其联系起来。由原先的单一的文本变成了可无限延伸、扩展的超级文本、立体文本
- HTML、JS、CSS、图片、字体、音频、视频等等文件,都是通过 HTTP(超文本传输协议) 在服务器和浏览器之间传输
- 每一次前后端通信,前端需要主动向后端发出请求,后端接收到前端的请求后,可以给出响应
- HTTP 是一个请求-响应协议
- HTTP 请求响应的过程
HTTP报文
-
请求报文和响应报文 浏览器向服务器发送请求时,请求本身就是信息,叫请求报文
服务器向浏览器发送响应时传输的信息,叫响应报文 -
HTTP 报文格式
-
请求 请求头:起始行+首部 请求体
-
请求种类 GET 请求,没有请求体,数据通过请求头携带
POST 请求,有请求体,数据通过请求体携带 -
响应 响应头:起始行+首部 响应体
HTTP方法
-
浏览器发送请求时采用的方法,和响应无关
GET、POST、PUT、DELETE
用来定义对于资源采取什么样的操作的,有各自的语义 -
HTTP 方法的语义
方法 | 用处 | 适用场景 |
---|---|---|
GET | 获取数据 | 获取资源(文件) |
POST | 创建数据 | 注册 |
PUT | 更新数据 | 修改个人信息,修改密码 |
DELETE | 删除数据 | 删除一条评论 |
这些方法虽然有各自的语义,但是并不是强制性的
- RESTful 接口设计 一种接口设计风格,充分利用 HTTP 方法的语义
- 通过用户 ID 获取个人信息,使用 GET 方法 www.imooc.com/api/http/ge…
- GET www.imooc.com/api/http/us…
- 注册新用户,使用 POST 方法 www.imooc.com/api/http/ad…
- POST www.imooc.com/api/http/us…
- 修改一个用户,使用 POST 方法 www.imooc.com/api/http/mo…
- PUT www.imooc.com/api/http/us…
- 删除一个用户,使用 POST 方法 www.imooc.com/api/http/de…
- DELETE www.imooc.com/api/http/us…
GET和POST方法
-
语义 GET:获取数据 POST:创建数据
-
发送数据 GET 通过地址在请求头中携带数据 ,能携带的数据量和地址的长度有关系,一般最多就几K
POST 既可以通过地址在请求头中携带数据,也可以通过请求体携带数据 ,能携带的数据量理论上是无限的
携带少量数据,可以使用 GET 请求,大量的数据可以使用 POST 请求
-
缓存 GET 可以被缓存,POST 不会被缓存
-
安全性 ?username=alex GET 和 POST 都不安全
发送密码或其他敏感信息时不要使用 GET,主要是避免直接被他人窥屏或通过历史记录找到你的密码
HTTP状态码
-
HTTP 状态码是什么 定义服务器对请求的处理结果,是服务器返回的
-
HTTP 状态码的语义 1xx:请求正在处理
2xx:成功
3xx: 重定向
- 301 moved permanenty,永久性重定向,表示资源已被分配了新的 URL
- 302 found ,临时性重定向,表示资源临时被分配了新的URL
- 303 see other ,表示资源存在着另一个 URL,应使用GET方法定向获取资源
- 304 not modified ,表示服务器允许访问资源﹐但因发生请求未满足条件的情况
- 307 temporary redirect , 临时重定向﹐和302含义相同
4xx:客户端错误
- 400 bad request ,请求报文存在语法错误
- 401 unauthorized ,表示发送的请求需要有通过HTTP认证的认证信息
- 403 forbidden .表示对请求资源的访问被服务器拒绝
- 404 not found ,表示服务器上没找到请求的资源
- 408 Request timeout,客户端请求超时
- 409 confict ,请求的资源可能引起冲突 5xx:服务器错误
- 500 internal server error ,表示服务器端在执行请求时发生了错误
- 501 Not Implemented,请求超出服务器能力范围
- 503 service unavailable ,表示服务器暂时处于超负载或正在停机维护,无法处理
- 505 http version not supported ,服务器不支持,或者拒绝支持在请求中的使用的HTTP版本 同样是重定向,302是HTTP1.0的状态码,在HTTP1.1版本的时候为了细化302又分出来了303和307 ,303则明确表示客户端应采用get方法获取资源,他会把post请求变成get请求进行重定向;307则会遵照浏览器标准,不会改变post
本地存储
cookie
- 初识cookie
- Cookie 是什么
Cookie 全称 HTTP Cookie,简称 Cookie
是浏览器存储数据的一种方式
因为存储在用户本地,而不是存储在服务器上,是本地存储
一般会自动随着浏览器每次请求发送到服务器端 - Cookie 有什么用 利用 Cookie 跟踪统计用户访问该网站的习惯,比如什么时间访问,访问了哪些页面,在每个网页的停留时间等
- 在浏览器中操作 Cookie 不要在 Cookie 中保存密码等敏感信息
- cookie的基本用法
- 写入 Cookie
document.cookie = 'username=zs';
document.cookie = 'age=18';
注 不能一起设置,只能一个一个设置 - 读取 Cookie
console.log(document.cookie);
//username=zs;age=18 读取的是一个由名值对构成的字符串,每个名值对之间由“; ”(一个分号和一个空格)隔开
- cookie的属性
- Cookie 的名称(Name)和值(Value)
最重要的两个属性,创建 Cookie 时必须填写,其它属性可以使用默认值
Cookie 的名称或值如果包含非英文字母,则写入时需要使用 encodeURIComponent() 编码,读取时使用 decodeURIComponent() 解码
document.cookie = `username=${encodeURIComponent('张三')}`;
一般名称使用英文字母,不要用中文,值可以用中文,但是要编码
- 失效(到期)时间
对于失效的 Cookie,会被浏览器清除
如果没有设置失效(到期)时间,这样的 Cookie 称为会话 Cookie
它存在内存中,当会话结束,也就是浏览器关闭时,Cookie 消失
想长时间存在,设置 Expires 或 Max-Age
expires
值为 Date 类型
document.cookie = `username=alex; expires=${new Date(
'2100-1-01 00:00:00'
)}`;
max-age
值为数字,表示当前时间 + 多少秒后过期,单位是秒
如果 max-age 的值是 0 或负数,则 Cookie 会被删除
document.cookie = 'username=alex; max-age=0';
以下几点了解即可
-
Domain 域
Domain 限定了访问 Cookie 的范围(不同域名) 使用 JS 只能读写当前域或父域的 Cookie,无法读写其他域的 Cookie -
Path 路径 Path 限定了访问 Cookie 的范围(同一个域名下)
使用 JS 只能读写当前路径和上级路径的 Cookie,无法读写下级路径的 Cookie
document.cookie = 'username=alex; path=/course/list';
document.cookie = 'username=alex; path=/1.Cookie/';
当 Name、Domain、Path 这 3 个字段都相同的时候,才是同一个 Cookie -
HttpOnly 设置了 HttpOnly 属性的 Cookie 不能通过 JS 去访问
-
Secure 安全标志 Secure 限定了只有在使用了 https 而不是 http 的情况下才可以发送给服务端
Domain、Path、Secure 都要满足条件,还不能过期的 Cookie 才能随着请求发送到服务器端
-
cookie的封装(在vscode代码中)
-
cookie的注意事项
- 前后端都可以创建 Cookie
- Cookie 有数量限制
每个域名下的 Cookie 数量有限
当超过单个域名限制之后,再设置 Cookie,浏览器就会清除以前设置的 Cookie - Cookie 有大小限制 每个 Cookie 的存储容量很小,最多只有 4KB 左右
localstorage
-
localStorage 是什么 localStorage 也是一种浏览器存储数据的方式(本地存储),它只是存储在本地,不会发送到服务器端
单个域名下的 localStorage 总大小有限制 -
localStorage 的基本用法 console.log(localStorage);
- setItem() localStorage.setItem('username', 'alex');
- length console.log(localStorage.length);
- getItem() console.log(localStorage.getItem('username'));
- 获取不存在的返回 null
- removeItem() localStorage.removeItem('username'); 删除不存在的 key,不报错 localStorage.removeItem('name');
- clear() localStorage.clear();
- 使用 localStorage 实现自动填充
const loginForm = document.getElementById('login');
const btn = document.getElementById('btn');
const username = localStorage.getItem('username');
if (username) {
loginForm.username.value = username;
}
btn.addEventListener(
'click',
e => {
e.preventDefault();
// 数据验证
// console.log(loginForm.username.value);
localStorage.setItem('username', loginForm.username.value);
loginForm.submit();
},
false
);
总结,cookie、localstorage、sessionStorage三者的异同
- 生命周期
- cookie:可设置失效时间,没有设置的话,默认是关闭浏览器后失效
- localStorage:除非被手动清除,否则将会永久保存。
- sessionStorage: 仅在当前网页会话下有效,关闭页面或浏览器后就会被清除。
- 存放数据大小
- cookie:4KB左右
- localStorage和sessionStorage:可以保存5MB的信息。
- http请求
- cookie:每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题
- localStorage和sessionStorage:仅在客户端(即浏览器)中保存,不参与和服务器的通信
- 易用性
- cookie:需要程序员自己封装,源生的Cookie接口不友好
- localStorage和sessionStorage:源生接口可以接受,亦可再次封装来对Object和Array有更好的支持
Ajax
Ajax基础
- Ajax 是什么 Ajax 是 Asynchronous JavaScript and XML(异步 JavaScript 和 XML)的简写
-
Ajax 中的异步:可以异步地向服务器发送请求,在等待响应的过程中,不会阻塞当前页面,浏览器可以做自己的事情。直到成功获取响应后,浏览器才开始处理响应数据
-
XML(可扩展标记语言)是前后端数据通信时传输数据的一种格式,XML 现在已经不怎么用了,现在比较常用的是 JSON
-
Ajax 其实就是浏览器与服务器之间的一种异步通信方式 使用 Ajax 可以在不重新加载整个页面的情况下,对页面的某部分进行更新
例:注册界面
- 搭建 Ajax 开发环境
Ajax 需要服务器环境,非服务器环境下,很多浏览器无法正常使用 Ajax
Live Server在vscode中安装本地环境
Ajax的基本用法
- XMLHttpRequest
- Ajax 想要实现浏览器与服务器之间的异步通信,需要依靠 XMLHttpRequest,它是一个构造函数 不论是 XMLHttpRequest,还是 Ajax,都没有和具体的某种数据格式绑定
- Ajax 的使用步骤
2.1. 创建 xhr 对象
const xhr = new XMLHttpRequest();
2.2. 监听事件,处理响应
当获取到响应后,会触发 xhr 对象的 readystatechange 事件,可以在该事件中对响应进行处理
xhr.addEventListener('readystatechange', () => {}, fasle);
xhr.onreadystatechange = () => {
if (xhr.readyState !== 4) return;
if ((xhr.status >= 200) & (xhr.status < 300) || xhr.status === 304) {
// console.log('正常使用响应数据');
console.log(xhr.responseText);
}
};
readystatechange 事件也可以配合 addEventListener 使用,不过要注意,IE6~8 不支持 addEventListener
为了兼容性,readystatechange 中不使用 this,而是直接使用 xhr
由于兼容性的原因,最好放在 open 之前
- readystatechange 事件监听 readyState 这个状态的变化
它的值从 0 ~ 4,一共 5 个状态
0:未初始化。尚未调用 open()
1:启动。已经调用 open(),但尚未调用 send()
2:发送。已经调用 send(),但尚未接收到响应
3:接收。已经接收到部分响应数据
4:完成。已经接收到全部响应数据,而且已经可以在浏览器中使用了
2.3. 准备发送请求
xhr.open(
'HTTP 方法 GET、POST、PUT、DELETE',
'地址 URL https://www.imooc.com/api/http/search/suggest?words=js ./index.html ./index.xml ./index.txt',
true
);
调用 open 并不会真正发送请求,而只是做好发送请求前的准备工作
2.3. 发送请求
调用 send() 正式发送请求
send() 的参数是通过请求体携带的数据
- 使用 Ajax 完成前后端通信
const url = 'https://www.imooc.com/api/http/search/suggest?words=js';
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState !== 4) return;
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
console.log(xhr.responseText);
//{"code":200,"data":[{"word":"jsp"},{"word":"js"},{"word":"json"},{"word":"js \u5165\u95e8"},{"word":"jstl"}]}
console.log(typeof xhr.responseText); //string
}
};
xhr.open('GET', url, true);
xhr.send(null);
GET请求
- 携带数据
GET 请求不能通过请求体携带数据,但可以通过请求头携带
xhr.send('sex=male');
不会报错,但不会发送数据
2. 数据编码
如果携带的数据是非英文字母的话,比如说汉字,就需要编码之后再发送给后端,不然会造成乱码问题
可以使用 encodeURIComponent() 编码
POST请求
- 携带数据 POST 请求主要通过请求体携带数据,同时也可以通过请求头携带
- 如果想发送数据,直接写在 send() 的参数位置,一般是字符串
xhr.send('username=alex&age=18');
- 不能直接传递对象,需要先将对象转换成字符串的形式
xhr.send({username: 'alex',age: 18 });
- 数据编码
xhr.send(`username=${encodeURIComponent('张三')}&age=18`);
JSON
-
JSON是Ajax发送和接受数据的一种格式 JSON 全称是 JavaScript Object Notation
{"code":200,"data":[{"word":"jsp"},{"word":"js"},{"word":"json"},{"word":"js \u5165\u95e8"},{"word":"jstl"}]}
-
为什么需要 JSON
JSON 有 3 种形式,每种形式的写法都和 JS 中的数据类型很像,可以很轻松的和 JS 中的数据类型互相转换
- JS->JSON->PHP/Java
- PHP/Java->JSON->JS
JSON的三种形式
- 简单值形式
.json
JSON 的简单值形式就对应着 JS 中的基础数据类型: 数字、字符串、布尔值、null
- 注意事项
① JSON 中没有 undefined 值
② JSON 中的字符串必须使用双引号
③ JSON 中是不能注释的
- 对象形式 JSON 的对象形式就对应着 JS 中的对象
- 注意事项
JSON 中对象的属性名必须用双引号,属性值如果是字符串也必须用双引号
JSON 中只要涉及到字符串,就必须使用双引号
不支持 undefined
- 数组形式 JSON 的数组形式就对应着 JS 中的数组
- 注意事项
数组中的字符串必须用双引号
JSON 中只要涉及到字符串,就必须使用双引号
不支持 undefined
xhr.open('GET', './arr.json', true);
JSON的常用方法
-
JSON.parse() JSON.parse() 可以将 JSON 格式的字符串解析成 JS 中的对应值
一定要是合法的 JSON 字符串,否则会报错 -
JSON.stringify() JSON.stringify() 可以将 JS 的基本数据类型、对象或者数组转换成 JSON 格式的字符串
console.log(
JSON.stringify({
username: 'alex',
age: 18
})
); //{username:'alex',age:18}
- 使用 JSON.parse() 和 JSON.stringify() 封装 localStorage
跨域
- 跨域是什么
同域,不是跨域 const url = './index.html';
http://127.0.0.1:5500
不同域,跨域,被浏览器阻止 const url = 'www.imooc.com'; const xhr = new XMLHttpRequest();
Access to XMLHttpRequest at 'https://www.imooc.com/' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource
向一个域发送请求,如果要请求的域和当前域是不同域,就叫跨域
不同域之间的请求,就是跨域请求
- 什么是不同域,什么是同域 https(协议)://www.imooc.com(域名):443(端口号)/course/list…
协议、域名、端口号,任何一个不一样,就是不同域
与路径无关,路径一不一样无所谓
不同域
https://www.imooc.com:443/course/list
http://www.imooc.com:80/course/list
http://www.imooc.com:80/course/list
http://m.imooc.com:80/course/list
http://imooc.com:80/course/list
同域
http://imooc.com:80
http://imooc.com:80/course/list
3. 跨域请求为什么会被阻止
阻止跨域请求,其实是浏览器本身的一种安全策略--同源策略
其他客户端或者服务器都不存在跨域被阻止的问题
- 跨域解决方案
① CORS 跨域资源共享
② JSONP
优先使用 CORS 跨域资源共享,如果浏览器不支持 CORS 的话,再使用 JSONP
CORS跨域资源共享
- CORS 是什么
-
Access-Control-Allow-Origin: * 表明允许所有的域名来跨域请求它,* 是通配符,没有任何限制
-
只允许指定域名的跨域请求
Access-Control-Allow-Origin: http://127.0.0.1:5500
-
使用 CORS 跨域的过程 (了解)
① 浏览器发送请求
② 后端在响应头中添加 Access-Control-Allow-Origin 头信息
③ 浏览器接收到响应
④ 如果是同域下的请求,浏览器不会额外做什么,这次前后端通信就圆满完成了
⑤ 如果是跨域请求,浏览器会从响应头中查找是否允许跨域访问
⑥ 如果允许跨域,通信圆满完成
⑦ 如果没找到或不包含想要跨域的域名,就丢弃响应结果 -
CORS 的兼容性 IE10 及以上版本的浏览器可以正常使用 CORS
JSONP
-
JSONP 的原理 script 标签跨域不会被浏览器阻止
JSONP 主要就是利用 script 标签,加载跨域文件 -
使用 JSONP 实现跨域 服务器端准备好 JSONP 接口
www.imooc.com/api/http/js…
手动加载 JSONP 接口或动态加载 JSONP 接口
const script = document.createElement('script');
script.src =
'https://www.imooc.com/api/http/jsonp?callback=handleResponse';
document.body.appendChild(script);
// 声明函数
const handleResponse = data => {
console.log(data);
};
XHR对象
属性
- responseType 和 response 属性 responseText 只能在没有设置 responseType 或者 responseType = '' 或 'text' 的时候才能使用
xhr.open('GET', url, true);
// xhr.responseType = '';
// xhr.responseType = 'text';
xhr.responseType = 'json';
xhr.send(null);
IE6~9 不支持,IE10 开始支持
-
timeout 属性 设置请求的超时时间(单位 ms)
(在xhr.open()之后)xhr.timeout = 10000;
IE6~7 不支持,IE8 开始支持 -
withCredentials 属性 指定使用 Ajax 发送请求时是否携带 Cookie
使用 Ajax 发送请求,默认情况下,同域时,会携带 Cookie;
跨域时,不会
xhr.withCredentials = true;
最终能否成功跨域携带 Cookie,还要看服务器同不同意
IE6~9 不支持,IE10 开始支持
方法
1. abort()
终止当前请求
一般配合 abort 事件一起使用
(在xhr.send()之后)
xhr.abort();
- setRequestHeader()
可以设置请求头信息
xhr.setRequestHeader(头部字段的名称, 头部字段的值);
(在xhr.open()之后)
请求头中的 Content-Type 字段用来告诉服务器,浏览器发送的数据是什么格式的
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.setRequestHeader('Content-Type', 'application/json');
事件
- load 事件 响应数据可用时触发
xhr.addEventListener(
'load',
() => {
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
console.log(xhr.response);
}
},
false
);
IE6~8 不支持 load 事件
- error 事件 请求发生错误时触发
xhr.addEventListener(
'error',
() => {
console.log('error');
},
false
);
IE10 开始支持
- abort 事件 调用 abort() 终止请求时触发
xhr.addEventListener(
'abort',
() => {
console.log('abort');
},
false
);
xhr.open('GET', url, true);
xhr.send(null);
xhr.abort();
IE10 开始支持
- timeout 事件 请求超时后触发
xhr.addEventListener(
'timeout',
() => {
console.log('timeout');
},
false
);
xhr.open('GET', url, true);
xhr.timeout = 10;
xhr.send(null);
IE8 开始支持
Ajax进阶
FormData
-
使用 Ajax 提交表单
-
FormData 的基本用法 通过 HTML 表单元素创建 FormData 对象
const fd = new FormData(表单元素);
xhr.send(fd);
通过 append() 方法添加数据
const fd = new FormData(表单元素);
fd.append('age', 18);
fd.append('sex', 'male');
xhr.send(fd);
IE10 及以上可以支持
(待补充)
Ajax扩展
axios
- axios 是什么
axios 是一个基于 Promise 的 HTTP 库,可以用在浏览器和 node.js 中
第三方 Ajax 库
- axios 的基本用法 引入 axios
const url = 'https://www.imooc.com/api/http/search/suggest?words=js';
axios(url, {
method: 'post',
// 请求时的头信息
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
// 'Content-Type': 'application/json'
},
// 通过请求头携带的数据
params: {
username: 'alex'
},
// 通过请求体携带的数据
// application/json
// data: {
// age: 18,
// sex: 'male'
// }
// application/x-www-form-urlencoded
data: 'age=18&sex=male'
// timeout: 10
// withCredentials: true
})
.then(response => {
console.log(response);
console.log(response.data.data);
})
.catch(err => {
console.log(err);
});
axios
.get(url, {
params: {
username: 'alex'
}
})
.then(response => {
console.log(response);
});
axios
.post(url, 'username=alex&age=18')
.then(response => {
console.log(response);
})
.catch(err => {
console.log(err);
});
Fetch
Ajax应用
(待补充)