前后端的理解
-
前端:h5 c3 js jq vue
把后端给的数据展示在页面上(显示列表页面),把前端的数据传递给后端,让后端存储起来
-
后端 :node.js(不涉及前端的省略)
当前端需要数据的时候,后端从数据库里面拿到数据给前端,把前端传递的数据存储在数据库中
-
数据库:专门让后端进行数据的增删改查
- 注意:
前端不能操作数据库,如果想对数据库进行操作,就要把信息告诉后端,由后端进行数据库操作,把信息反馈给前端
eg:一个注册功能的实现的整个流程
前端=》后端=》数据库=》后端=》前端
服务器
简单理解为 一台在网络的‘另一头’的一台电脑‘运行’了一些特殊的软件
作用:
浏览器不支持后端代码的运行,但在服务器环境下可运行服务端代码即后端代码
服务器工作流程:
当一台电脑运行了一个服务器环境后,在这台电脑上,就会有一个文件夹被对外开放,叫‘服务器空间’。只要你在这个服务器空间里面放上对应的HTML文件,其他网络上的小伙伴就能根据网线找到你这台电脑,找到对应的文件夹(TCP请求),就可以看到里面的页面了(只读权限)
找到对应这台电脑上的那个服务器软件 叫 端口号 (可以理解为一个软件的门牌号码),如果能找到这个软件,就能找到这个软件开放的那个文件夹(服务器空间),也就是说百度提前在这个文件夹里放好一个html页面,我们就能看到这个页面了。
eg:
https://www.baidu.com/
这是一个地址url,能看到百度的首页
https =>传输协议 www.baidu.com =>域名(ip地址)
在网路环境中,每一个电脑都有自己的ip地址(123.23.14.78),数字不好记,网络上有一个高辨识度的名字来代表这个ip地址,就是通过域名能找到百度家的服务器的那个电脑。
- 了解:
http 传输协议,浏览器会自动帮你添加一个80端口
https 传输协议,浏览器会自动帮你添加一个443端口
请求方式
前端和后端通信的方式
常见的请求方式:
get:多用于向服务器获取一些信息
post:多用于向服务器传递信息,并让服务器存储起来
put:多用于向服务器传递信息,并让服务器全部更新数据并存储起来
delete:多用于让服务器删除一些信息
head:不需要响应体,主要是为了获取响应头信息
patch:多用于向服务器传递信息,并让服务器部分更新数据并存储起来
connect:预留方式,管道连接改成代理连接的方式
option:用于允许前端查看服务器性能(服务端同意)
get和post请求的区别
get:
- 倾向于向服务器获取数据
- 直接在地址栏后面拼接(请求体可以是空的)
- 大小限制为2kb左右(因为浏览器的地址栏长度有限制)
- 会被浏览器主动缓存
- 相对于POST不是很安全(因为明文发送)
- 数据格式必须是url编码格式,如果不是会自动转化成url编码
post:
- 倾向于向服务器传递数据
- 在请求体里面传递过去(地址后面是没有任何参数的)
- 理论上大小没有限制(服务器端可能会限制)
- 不会被浏览器主动缓存,需要手动设置
- 相对GET比较安全(暗文发送)
- 数据格式理论上无所谓,但是要和请求头中的content-type一致(请求头里面的content-type表示请求体中的数据格式)
ajax
a:async 异步 j:JavaScript a:and x:xml 一种语言,用来传输内容的
是一个前端可以和后端交互的手段即异步的xml和js交互手段,js语言里面的一个方法(能力)
- 前端可以通过ajax给后端发送数据 – 请求:request
- 后端可以通过ajax给前端发送数据 – 响应:response
在没有ajax之前,在浏览器地址栏输入一个地址,客户端就会显示一个页面、显示一个图片或者是一个json字符串。
现在我们可以使用js的内置ajax对象构造函数,创建ajax对象,来帮助我们使用指定的请求方式,请求指定的url地址存放的内容,然后响应内容给ajax对象。有了ajax,也就是js去请求一个后端的url地址,url地址对应的资源不会直接显示在浏览器上,而是把资源给js这个语言进行处理。如果你想要将处理过的资源显示在页面上,我们可以通过js渲染,而不是刷新整个页面。
- 渲染到页面的方法:
document.write()、innerHTML()、innerText()、appendChild()
发送ajax请求的步骤:
-
创建一个ajax对象
实例化一个构造函数,得到一个对象,这个对象就能帮我发ajax请求
let xhr = new XMLHttpRequest()
-
配置请求信息
使用创建好的ajax对象来帮我完成配置请求信息,你要用什么方式请求,要请求哪一个url地址或者说后端服务器地址,想发送一个同步请求还是异步请求(默认是异步)
语法:ajax对象.open(请求方式,请求地址,是否异步)
- 注意:请求方式不区分大小写,是否异步可以不写,默认异步
eg:以GET的请求方式,请求地址http://localhost:8888
xhr.open('get','http://localhost:8888/test/first') // localhost:是一个域名,如果服务器就在自己代码运行的那个电脑上我们的域名就可以写成localhost // 127.0.0.1:是一个ip地址,如果服务器就在自己代码运行的那个电脑上,我们的ip就可以写成127.0.0.1
-
把这个配置好的请求发送出去
语法:ajax对象.send()
-
接收后端的响应
因为现在是js和后端交互,而不是浏览器和后端交互,所以后端返还的响应资源就给了js,我们就要用一个事件来接受资源
语法:ajax对象.onload = function(){}
eg:发送带参数的ajax
document.querySelector('button').onclick = function () {
let xhr = new XMLHttpRequest()
// 1.get请求 带参数
xhr.open('get', 'http://localhost:8888/test/third?name=你好&age=12')
xhr.send()
// 2.post请求 带参数
xhr.open('POST', 'http://localhost:8888/test/fourth')// post携带的参数写在send后面的括号里
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
xhr.send('name=你好&age=12')
xhr.onload = function () {
document.querySelector('h3').innerHTML = xhr.response
}
}
传输协议http
一个http请求的发起步骤(这个请求只能由前端发起,并且这四个步骤缺一不可):
-
建立连接
基于TCP/IP协议的三次握手
目的:保证前后端都可以正常通信,前后端都知道对方可以正常收发信息
-
前端发送请求(request)
每一个请求都是以请求报文的形式发送,我们写好了必要的内容,浏览器会自动帮我们组装成固定格式的报文
报文:有固定格式的文章
请求报文:就是一个写给后端的有固定格式的信件
请求报文的内容:
请求报文行(请求行)、请求方式、请求路径(你向服务器请求的是什么东西)、传输协议版本
一个完整的请求报文:
-
请求行(请求报文行):说明是什么请求,请求哪一个地址
-
请求头(请求报文头):一些本次请求的描述信息
-
cotent-type : 前端给后端的数据的数据格式
-
cookie:“浏览器的存储空间之一”
-
host:请求的主机
-
-
请求空行(请求报文空行):分隔请求头和请求体的一个空行
-
请求体(请求报文体):前端给后端传递的真实数据
-
-
后端返回响应(response)
每一个响应都以响应报文的形式返回,也是一个固定格式的信件
一个完整的响应报文:
-
状态行(响应状态行):传输协议(http/1.1)、状态码(200)、状态码的简单描述(ok)
-
响应头(响应报文头): 一些本次响应的描述信息
-
Date:服务器时间
-
Server:服务器信息
-
Content-Length:后端返回的数据长度
-
Content-Type:后端给前端的数据格式
-
-
响应体(响应报文体): 后端给前端端传递的真实数据
-
-
断开连接
基于TCP/IP协议的四次挥手
目的:保证客户端与服务器不再进行通讯
eg:前端要和后端说两次事情
- 建立连接 -> 说第一个事情 -> 后端把第一个事情做完反馈结果给前端 -> 断开连接
- 建立连接 -> 说第二个事情 -> 后端把第二个事情做完反馈结果给前端 -> 断开连接
常见的http响应状态码
在一个http请求的响应报文中,状态行有一个响应状态码Status Code,用来描述本次响应的状态
通常情况下会出现5种状态码:
100-199、200-299、300-399、400-499、500-599
-
1开头:
表示请求继续,很少见,一般我们看不到
- 100:继续发送请求,前面的一部分内容服务器已经收到了,正等待后续内容
- 101:请求者已经准备切换协议,服务器也表示同意
-
2开头:
表示成功,各种意义上的成功
-
200:标准请求成功(一般表示服务器提供的是网页)
-
201:创建成功(一般是注册的时候,表示新用户的信息已经添加到数据库)
-
203:表示服务器已经处理了请求,但是返回的信息可能来自另一个源
-
204:服务端已经成功处理了请求,但是没有任何数据返回
-
-
3开头:
3表示成功,但一般表示重定向
-
301:永久重定向
-
302:临时重定向
-
304:使用的是缓存的数据
-
305:使用的是代理的数据
-
-
4开头:
表示客户端出现了错误
-
400:请求的语法服务端不认识
-
401:未授权
-
403:服务器拒绝了你的请求
-
404:服务器找不到你请求的url
-
407:你的设置的代理没有授权
-
408:请求超时
-
410:你请求的数据已经被服务器永久的删除了
-
-
5开头:
表示服务端出现了错误
-
500:服务器内部错误
-
503:服务器当前不可用(过载或者维护了)
-
505:请求的协议服务器不支持
-
cookie
是一个在客户端的存储空间,当你的代码运行在浏览器的时候,一大部分浏览器功能是用来给页面显示的,一小部分位置是专门来存储一些数据,cookie空间里面可以以字符串的形式来存储一些数据, 每一个cookie信息包含过期时间,达到时间时,cookie自动删除
- 数据格式:必须是 key=value,多条数据中间用 ; 分割key1=value1;key2=value
cookie的特点:
-
按照域名存储:
你在哪一个域名下存储的内容,就在哪一个域名下使用,其他域名都用不了
eg:cookie就相当于工牌,你在哪个公司,就用哪公司的工牌,只能在这个公司用
-
存储空间大小限制:
4kb,50条数据左右
eg:cookie就相当于工牌,一个工牌上不会也不可以记录太多的东西
-
时效性:
默认是会话级别的时效性,可以手动设置,例如七天后、两个小时后
eg:cookie就相当于工牌,有临时访客的临时工牌,正式员工有正式的
-
请求自动携带参数:
当你的cookie空间里面有内容的时候,只要是当前域名下的任意一个请求,都会自动携带cookie,将里面的数据放在请求头里携带给后端,cookie里面有多少就自动携带多少。如果cookie没有内容就不会携带任何参数给后端
eg:cookie就相当于工牌,不管你的工牌上有多少信息(电话职位姓名),只要去别的部门办业务,工牌上的所有信息都可以给别人看
-
前后端都可以操作:
前端可以通过js操作cookie进行cookie内容的增删改查,后端也可以通过后端语言进行cookie空间的增删改查
cookie的基本操作
JavaScript 可以使用 document.cookie 属性来创建 、读取、增加及删除 cookie
-
设置cookie:
document.cookie="username=hello"
-
获取cookie:
直接使用document.cookie
如果cookie里面只有一条cookie数据,查询字符串“a=100”
如果cookie里面有多条cookie数据,字符串“a=100; b=200; c=300”
如果里面没有任何数据,就是一个空行即空字符串
-
增加
// 设置cookieusername和时间 var odate=new Date(); //设置时间为当前的第二天 odate.setDate(odate.getDate()+1) document.cookie="username=hello;expires="+odate;
-
删除cookie
var odate=new Date(); odate.setDate(odate.getDate()-1) document.cookie="username=hello;expires="+odate;
-
修改cookie(第二个会覆盖第一个):
document.cookie="username=hello1" document.cookie="username=hello2" console.log(document.cookie) //username=hello2
封装cookie
前端操作cookie比较复杂,为了调用方便,我们把前端操作的cookie操作封装成函数
-
setCookie():用来设置,修改,删除
function setCookie(key, value, expires) { // 首先判断有没有传递过期时间 if (expires) { // 准备一个时间对象 let time = new Date() time.setTime(time.getTime() - 8 * 60 * 60 * 1000 + expires * 1000) // 设置我准备设置的cookie document.cookie = `${key}=${value};expires=${time}` } else { // 设置我准备设置的cookie document.cookie = `${key}=${value}` } } // 使用一下 setCookie('a', 100, 50)
-
getCookie():获取cookie
function getCookie(key) { // 准备一个字符串 let str = '' let tmp = document.cookie.split('; ')// 分号后面有空格 tmp.forEach(function (item) { let k = item.split('=') if (k[0] === key) { str = k[1] } }) return str } let a = getCookie('b')
跨域
跨域本质是浏览器基于同源策略的一种安全手段,同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能。当浏览器执行脚本时会检查是否同源,只有同源的脚本才会执行,如果不同源即为跨域。
所谓同源(即指在同一个域)具有以下三个相同点:
-
协议相同(protocol)
-
主机(域名)相同(host)
-
端口相同(port)
http 127.0.0.1 :2937
你可以发送请求,但是只能向自己家的服务器发送请求,向别人家的服务器发送的话会有问题。也就是当协议、端口、主机其中一项不相同的时候,即触发了“同源策略”请求(非同源请求),这时候就会产生跨域。
Ajax 发起的跨域 HTTP 请求,结果被浏览器拦截,同时Ajax 请求不能携带与本网站不同源的 Cookie。如当使用ajax 提交非同源的请求时,浏览器就会阻止请求。
我的服务器会报这个错 Access to XMLHttpRequest at ‘http://localhost:8888/test/first’ from origin ‘http://127.0.0.1:2937’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
发送请求的服务器 http://127.0.0.1:2937/
请求目标的服务器 http://localhost:8888
跨域的解决方案
-
jsonp
十多年前火爆前端的跨域解决方案,至今还在使用,这个解决方案和ajax没有任何关系。
script、img、iframe、link、video、audio 等带有 src 属性的标签可以跨域请求和执行资源,src属性不受浏览器同源策略影响,JSONP 利用这一点“漏洞”实现跨域。
- script标签:默认有一个type属性,默认值是text/javascript,不管src请求的是什么文件地址,都是把文件里面的所有内容当做字符串读取出来,把读取出来的字符串当做js代码来执行
- 缺点:只能get 请求方式(派生请求都是get),易受到 XSS攻击
-
cors
7年前火爆前端的跨域解决方案,目前占市场的45%,这个解决方案跟前端没有任何关系,在开发阶段
别人服务器允许域名请求我,我需要设置允许跨域的响应头:
- 用cors插件,在服务器代码里 npm i cors
- 在后端服务器上书写可以允许哪些请求头可以访问我的服务器
- 缺点: 忽略 cookie,浏览器版本有一定要求
-
proxy(服务器代理)
在浏览器同源的位置设置一个代理服务器,请求服务器发送请求给代理服务器,由代理服务器 转发请求给 目标服务器,由目标服务器 把响应内容返回给 代理服务器,由代理服务器 再把响应内容返回给 请求服务器,请求服务器 给浏览器数据 渲染
设置代理服务器步骤:
- 打开我的后端node代码
- 下载代理请求的第三方插件 npm i http-proxy-middleware
- 需要在后端代码中引入插件
代理分为2种:
-
正向代理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Adf4vsVt-1690298537158)(C:\Users\roawa\AppData\Roaming\Typora\typora-user-images\image-20230720150908546.png)]
有一个客户需要向一个非同源的目标服务器B发送请求,我们搭建一个和客户端同源的代理服务器A。
由客户端发送对某一个目标服务器的请求,代理服务器在中间将请求转发给该目标服务器,因为同源策略是限制客户端的,服务器之间没有限制,目标服务器将结果返回给代理服务器,代理服务器再将结果返回给客户端。
-
反向代理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nev1scuK-1690298537159)(C:\Users\roawa\AppData\Roaming\Typora\typora-user-images\image-20230720151013566.png)]
当我请求一个服务器的时候,其实请求的是服务器端设置的代理服务器,由代理服务器把许多大量的请求分发给不同的服务器进行处理,再由服务器把响应的结果给代理服务器,代理服务器返回给客户端
-
一般用来做负载均衡:
如果服务器集群中有负荷较高者,反向代理通过URL重写,根据连线请求从负荷较低者获取与所需相同的资源或备援。可以有效降低服务器压力,增加服务器稳定性
-