網(wǎng)站怎么做最省錢百度資源搜索
一.Cookie和Session
Cookie和Session都是用于在Web應(yīng)用中跟蹤用戶狀態(tài)的技術(shù)。Cookie是存儲(chǔ)在用戶瀏覽器中的小文本文件,由服務(wù)器發(fā)送給瀏覽器。當(dāng)用戶再次訪問(wèn)同一網(wǎng)站時(shí),瀏覽器會(huì)把Cookie信息發(fā)送回服務(wù)器。例如,網(wǎng)站可以利用Cookie記住用戶的登錄狀態(tài)、語(yǔ)言偏好等信息。Cookie有一定的有效期,可以設(shè)置過(guò)期時(shí)間。Session是存儲(chǔ)在服務(wù)器端的數(shù)據(jù)結(jié)構(gòu),用于跟蹤用戶的會(huì)話狀態(tài)。服務(wù)器為每個(gè)用戶(通常是通過(guò)用戶的首次請(qǐng)求)創(chuàng)建一個(gè)Session,會(huì)給用戶分配一個(gè)唯一的標(biāo)識(shí)符(Session ID),這個(gè)ID一般通過(guò)Cookie或URL參數(shù)等方式傳遞給瀏覽器。當(dāng)用戶在網(wǎng)站的不同頁(yè)面之間跳轉(zhuǎn)時(shí),瀏覽器會(huì)發(fā)送Session ID,服務(wù)器根據(jù)這個(gè)ID來(lái)識(shí)別用戶并獲取對(duì)應(yīng)的會(huì)話數(shù)據(jù),如購(gòu)物車中的商品信息等。
二.Cookie和Session的聯(lián)系與區(qū)別
1.cookie是什么
在瀏覽器訪問(wèn)服務(wù)器之前,此時(shí)你的瀏覽器對(duì)于這個(gè)服務(wù)器是一無(wú)所知的,你的瀏覽器上是沒(méi)有任何和這個(gè)服務(wù)器相關(guān)的數(shù)據(jù)的。在網(wǎng)頁(yè)開發(fā)中用戶獲取數(shù)據(jù)和服務(wù)器發(fā)送數(shù)據(jù)會(huì)產(chǎn)生很多“臨時(shí)性”的數(shù)據(jù)。臨時(shí)性的數(shù)據(jù)有的可以放在服務(wù)器這邊存儲(chǔ),有的可以放在瀏覽器上,用戶下次用可以直接獲取到。
比如嗶哩嗶哩中倍速播放,藍(lán)光模式這種數(shù)據(jù)就是臨時(shí)數(shù)據(jù),用戶下次再點(diǎn)開還是倍速藍(lán)光。
瀏覽器要保存數(shù)據(jù)為什么要放在cookie上,直接放硬盤上不行嗎?
答案:不行,如果讓網(wǎng)頁(yè)能輕易的訪問(wèn)你的系統(tǒng)文件是非常危險(xiǎn)的有可能會(huì)中病毒讓電腦奔潰或者數(shù)據(jù)刪掉。為了保證安全瀏覽器會(huì)對(duì)網(wǎng)頁(yè)的功能做出限制,禁止訪問(wèn)硬盤。為了能保證安全又能存儲(chǔ)數(shù)據(jù),瀏覽器就提供了cookie功能。
cookie是按照鍵值對(duì)的方式存儲(chǔ)一些字符串。這些鍵值對(duì)往往是服務(wù)器返回來(lái)的。瀏覽器把這些鍵值對(duì)按照域名進(jìn)行分類存儲(chǔ),不同的網(wǎng)站cookie是獨(dú)立的。這些cookie的內(nèi)容是程序員自己定義的。
一個(gè)網(wǎng)站中cookie中會(huì)存儲(chǔ)很多鍵值對(duì),往往會(huì)有一個(gè)很重要的鍵值對(duì),用來(lái)統(tǒng)計(jì)用戶的信息。為了實(shí)現(xiàn)身份識(shí)別的效果,不僅僅需要cookie來(lái)支持,在服務(wù)器這邊也需要session來(lái)支持。
2.舉例
假設(shè)你是第一次來(lái)醫(yī)院看病,首次掛號(hào)的時(shí)候,醫(yī)院會(huì)讓你辦一張就診卡。同時(shí)在醫(yī)院的系統(tǒng)里面會(huì)給你創(chuàng)建一份電子的檔案。當(dāng)你排了半天隊(duì),見到醫(yī)生,醫(yī)生讓你刷你的就診卡,你一刷卡你的各種信息就顯示在醫(yī)生的電腦上了。(就診卡里面存了你的身份標(biāo)識(shí),存了一串字符串,就像電話號(hào)碼一樣),電子檔案可以想象成哈希表,key是你的身份標(biāo)識(shí),value是你的電子檔案詳情。刷卡的時(shí)候讀卡器讀到我的身份標(biāo)識(shí)就可以知道我的電子檔案的詳情了。然后醫(yī)生讓你去抽血,做B超,尿檢。到了抽血科,醫(yī)生也是讓先刷卡,刷卡后知道你的病就知道要抽多少血哪里的血。來(lái)到B超科后同樣先刷卡拿到你的信息,就知道怎么檢查。檢查完畢后醫(yī)生還得刷卡拿信息取藥。當(dāng)你下一次來(lái)的時(shí)候醫(yī)生可以直接系統(tǒng)里面拿到你的信息和之前的取藥結(jié)果。
首次訪問(wèn)網(wǎng)站登錄成功后相當(dāng)于網(wǎng)站給你一個(gè)就診卡(身份標(biāo)識(shí),身份標(biāo)識(shí)也叫sessionid),身份標(biāo)識(shí)就通過(guò)服務(wù)器返回給瀏覽器的響應(yīng),保存在瀏覽器的cookie中了。與此同時(shí)人家網(wǎng)站服務(wù)器這邊也會(huì)創(chuàng)建出一個(gè)對(duì)應(yīng)的session(電子檔案),session中會(huì)記錄你的信息。網(wǎng)站服務(wù)器有很多個(gè)用戶,每個(gè)用戶都有自己的session,他們的sessionid各不相同,服務(wù)器會(huì)使用類似于HASH表這樣的方式,以sessionid為key,以session為value,把所有數(shù)據(jù)組織起來(lái)。后續(xù)訪問(wèn)網(wǎng)站的其他頁(yè)面(相當(dāng)于到各個(gè)科室做檢查),都會(huì)在請(qǐng)求的cookie字段中,帶上剛才這里的sessionid(也就是做檢查先刷卡,判斷你的信息),服務(wù)器就知道你當(dāng)前的用戶信息了。
我們通過(guò)抓包可以看到cookie里面的主要內(nèi)容:
是以鍵值對(duì)的方式去存儲(chǔ)的。鍵值對(duì)之間使用;分割,鍵和值使用=分割。在cookie中其中一個(gè)鍵值對(duì)是表示身份標(biāo)識(shí)的。
3.Session
session存在的意義也是為了讓用戶能夠保存一些自定義數(shù)據(jù),此時(shí)的session更像是一個(gè)Map<String,Object>。session在一個(gè)服務(wù)器上可以存在很多份,每個(gè)用戶都應(yīng)該有一個(gè)自己的session,應(yīng)該服務(wù)器有多個(gè)用戶,服務(wù)器就會(huì)用map的方式組織session.
4.總結(jié)
Cookie 是瀏覽器在本地持久化存儲(chǔ)數(shù)據(jù)的一種機(jī)制。
1.Cookie的數(shù)據(jù)從哪里來(lái)?服務(wù)器返回給瀏覽器的。
2.Cookie的數(shù)據(jù)長(zhǎng)啥樣?Cookie 中是鍵值對(duì)結(jié)構(gòu)的數(shù)據(jù).并且這里的鍵值對(duì)都是程序員自定義的。
3.Cookie有什么作用?Cookie 就可以在瀏覽器這邊存儲(chǔ)一些“臨時(shí)性的數(shù)據(jù)”,其中最典型的一種使用方式,就是用來(lái)存儲(chǔ)“身份標(biāo)識(shí)”。
4.Cookie到哪里去?Cookie的內(nèi)容會(huì)在下次訪問(wèn)該網(wǎng)站的時(shí)候,自動(dòng)的被帶到HTTP請(qǐng)求中。
5.Cookie怎么存的?瀏覽器按照不同的“域名”分別存儲(chǔ)Cookie,域名和域名之間的Cookie是不能干擾的Cookie 存儲(chǔ)在硬盤上的。Cookie存儲(chǔ)往往會(huì)有一個(gè)超時(shí)時(shí)間。
Cookie的超時(shí)時(shí)間也叫過(guò)期時(shí)間,是指瀏覽器存儲(chǔ)Cookie的有效時(shí)長(zhǎng)。當(dāng)服務(wù)器發(fā)送一個(gè)Cookie給瀏覽器時(shí),會(huì)設(shè)置這個(gè)Cookie的相關(guān)屬性,其中就包括過(guò)期時(shí)間。如果沒(méi)有設(shè)置超時(shí)時(shí)間,Cookie就會(huì)成為會(huì)話Cookie,它會(huì)在瀏覽器會(huì)話期間(即瀏覽器打開到關(guān)閉的時(shí)間段)一直存在,一旦瀏覽器關(guān)閉,會(huì)話Cookie就會(huì)被刪除。 要是設(shè)置了具體的超時(shí)時(shí)間,瀏覽器會(huì)根據(jù)這個(gè)時(shí)間來(lái)存儲(chǔ)Cookie。例如,設(shè)置超時(shí)時(shí)間為1小時(shí),那么從Cookie被設(shè)置開始計(jì)算,1個(gè)小時(shí)后,瀏覽器會(huì)自動(dòng)刪除這個(gè)Cookie,之后對(duì)相應(yīng)網(wǎng)站的請(qǐng)求就不會(huì)再帶上這個(gè)已經(jīng)過(guò)期的Cookie。這樣的機(jī)制可以控制用戶數(shù)據(jù)在客戶端存儲(chǔ)的周期,用于實(shí)現(xiàn)如用戶登錄狀態(tài)保持一定時(shí)間等功能。
二.核心方法
HttpServletRequest 類中的相關(guān)方法
HttpServletResponse類中的相關(guān)方法
HttpSession 類中的相關(guān)方法
一個(gè) HttpSession 對(duì)象里面包含多個(gè)鍵值對(duì). 我們可以往 HttpSession 中存任何我們需要的信息。
Cookie 類中的相關(guān)方法
HTTP 的 Cooke 字段中存儲(chǔ)的實(shí)際上是多組鍵值對(duì). 每個(gè)鍵值對(duì)在 Servlet 中都對(duì)應(yīng)了一個(gè) Cookie
對(duì)象。
通過(guò) HttpServletRequest.getCookies() 獲取到請(qǐng)求中的一系列 Cookie 鍵值對(duì)。
通過(guò) HttpServletResponse.addCookie() 可以向響應(yīng)中添加新的 Cookie 鍵值對(duì)。
1.獲取cookie
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
class User{public String username;public int age;
}
@WebServlet("/hello1")
public class HelloSevert extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {Cookie cookie = new Cookie("date","2024-10-24");resp.addCookie(cookie);Cookie cookie1 = new Cookie("date1","2024-10-25");resp.addCookie(cookie1);resp.getWriter().write("ok");}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {Cookie[] cookies = req.getCookies();for(Cookie x:cookies){System.out.println(x.getName()+":"+x.getValue());}}
}
通過(guò)抓包繼續(xù)觀察
2.獲取session
代碼示例: 實(shí)現(xiàn)用戶登陸
實(shí)現(xiàn)簡(jiǎn)單的用戶登陸邏輯
這個(gè)代碼中主要是通過(guò) HttpSession 類完成. 并不需要我們手動(dòng)操作 Cookie 對(duì)象。
import com.fasterxml.jackson.databind.ObjectMapper;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
import java.util.Enumeration;
class User{public String username;public int age;
}
@WebServlet("/hello1")
public class HelloSevert extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String user = req.getParameter("username");String password = req.getParameter("password");if(user==null||password==null||user.equals("")||password.equals("")){resp.setContentType("text/html,charset=utf8");resp.getWriter().write("用戶名錯(cuò)誤");return;}if(user.equals("aaa")&&password.equals("123")){HttpSession session = req.getSession(true);session.setAttribute("username",user);session.setAttribute("time",System.currentTimeMillis());}}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {HttpSession session = req.getSession();if(session==null){return;}String user = (String)session.getAttribute("username");System.out.println("user:"+user);}
}
HttpSession session = req.getSession(true);參數(shù)為true不存在會(huì)話就創(chuàng)建,存在會(huì)話就直接查詢。參數(shù)為false不存在就返回null,存在就直接查詢。
getSession 背后做的事情:
1.先讀取請(qǐng)求中的Cookie,看Cookie 里是否有JSESSIONID屬性,以及值是啥。如果沒(méi)有,就認(rèn)為需要?jiǎng)?chuàng)建新會(huì)話。如果有,就拿著這個(gè)id去查詢看看當(dāng)前的session 是否存在,要是 session存在,就直接返回該 session,要是session不存在,就準(zhǔn)備創(chuàng)建新會(huì)話。
2.當(dāng)前確實(shí)需要?jiǎng)?chuàng)建會(huì)話,就會(huì)創(chuàng)建出一個(gè)Session 對(duì)象,同時(shí)生成一個(gè)唯一的JSESSIONID。
以JSESSIONID為key,Session對(duì)象為value,把這個(gè)鍵值對(duì)給插入到服務(wù)器 上述的哈希表
3.剛才生成的JSESSIONID又會(huì)通過(guò)addCookie方法,加入到響應(yīng)中。此時(shí)響應(yīng)里就會(huì)帶有Set-Cookie字段,這里的值就是JSESSION=xxxxxxxxx通過(guò)響應(yīng),就把JSESSIONID返回到瀏覽器這邊了。