一句话简述cookie和session
两者都是保存用户信息和状态
Cookie保存在浏览器客户端,可修改
Session保存在服务端,创建后不能再修改
1.Cookie
先简单的用hyperf框架搭建环境并发送cookie(只要能发送或设置cookie即可)

在这里我设置cookie名字为name,值为zzz
现在访问路径查看头信息



set-Cookie的第二个参数path=/表示只能在当前作域才能访问
1.服务端生成Cookie在响应中通过set-Cookie头部告知客户端
2.后续的http请求中都会自动携带Cookie头部
如上图为第一次请求没有Cookie字段

再次请求时多了Cookie:name=zzz的字段
Cookie在HTTP协议中以明文方式存在(HTTPS除外)
RFC中的Cookie定义

不清理cookie,再发一个names的cookie


RFC中关于set-cookie的表述

因为Cookie是在HTTP中传输
所以有4kb的大小限制
想要存储更多建议使用jwt即token的形式
2.Session
session存储在服务端通常以以数据库,文件或redis缓存形式存在在HTTP协议中观察不到就不表述了
http的连接是无状态的,指当前请求不会依赖于上一个请求
http的请求是可以有状态的:
有状态的http请求:服务端保存session
无状态的http请求:请求可以通过cookie携带
跨域问题
什么是跨域?
相同的协议,相同的主机和域名
http://www.xx.com
与https://www.xx.com不同源,因为协议不同
与http://www.aa.com不同源,因为主机不同
与http://www.xx.com:90不同源,因为端口不同
哪些不能跨域访问
1.cookie,localstorage,indexdb
2.DOM节点无法获取
3.ajax请求不能发送
html中哪些会出现跨域问题(即不允许跨域访问)
<script><img>等携带src属性的标签
html中允许跨域写操作:
如表单提交和重定向请求
从不安全的域名下有表单提交过来,造成对本站数据的非法修改等问题,这就是常说的CSRF安全问题,即跨站伪造请求
当业务需要跨域访问时,我们如何做
RFC中推荐使用CORS解决方案
如果跨域访问本站点,需要在HTTP响应中显示的告诉浏览器该站点被允许
即在响应头添加对应的允许头文件
1.当简单的请求进行跨域(比如ajax请求)

代码测试一下:



结果出现跨域问题并明确提示增加Access头部


即像ajax这种简单的跨域访问我们需要在响应中携带Access-Control-Allow-Origin头部,浏览器才会放行,*表示所有域
2.复杂的请求(比如axios请求)
会在发送请求前先发送一个Options请求来检测可以用哪些跨域请求访问

在options请求中,access-control-request-method会告诉服务端即将发起什么请求
如access-control-request-method:POST表示下个请求为post
access-contril-request-headers会告诉服务端在这些请求中哪些响应头部会被使用到
如access-contril-request-headers:content-type表示content-type会被使用到
同理响应端
除了需要设置Access-Control-Allow-Origin还要一下几点:
access-control-allow-methods:表示哪些请求允许跨域访问
对应请求时的access-control-request-method头部
access-control-allow-headers表示哪些头部允许被使用
对应请求时的access-contril-request-headers
其他头部:




改成get和post方法

都能读取到数据,因为是简单请求,头部有设置Access-Control-Allow-Origin
修改nginx支持delete请求


此时可以读取数据
再观察请求的发送
delete请求在发送前多一次options请求

get请求只有一次

跨域总结
简单请求为get/post/head,这些请求只需要设置允许域即可,即Access-Controller-Origin
复杂请求会在发送前进行一次OPTIONS请求来读取头部是否允许进行该类请求至少需要设置二项
网友评论