http访问不到服务器_HTTP及会话技术解析:大魏Java记4
一、關于HTTP的協議版本
HTTP的全稱是Hyper Text Transfer Protocol的縮寫,即超級文本傳輸協議。HTTP協議用于定義瀏覽器與服務器之間交換數據的過程以及數據本身的格式。
HTTP是無狀態協議,對于事務處理沒有記錄能力。因此后續處理如果需要前面的信息,則它必須重傳,這會導致每次連接傳送的數據量增大.
HTTP目前主要有三個版本:1.0、1.1、2.0。
http1.0的交互過程如下圖所示:
缺陷:瀏覽器與服務器只保持短暫的連接,瀏覽器的每次請求都需要與服務器建立一個TCP連接(TCP連接的新建成本很高,因為需要客戶端和服務器三次握手),服務器完成請求處理后立即斷開TCP連接,服務器不跟蹤每個客戶也不記錄過去的請求;
解決方案:
添加頭信息——非標準的Connection字段Connection: keep-alive
http1.1:
改進點:
持久連接
引入了持久連接,即TCP連接默認不關閉,可以被多個請求復用,不用聲明Connection: keep-alive(對于同一個域名,大多數瀏覽器允許同時建立6個持久連接)
管道機制
即在同一個TCP連接里面,客戶端可以同時發送多個請求。
分塊傳輸編碼
即服務端沒產生一塊數據,就發送一塊,采用”流模式”而取代”緩存模式”。
新增請求方式
PUT:請求服務器存儲一個資源;
DELETE:請求服務器刪除標識的資源;
OPTIONS:請求查詢服務器的性能,或者查詢與資源相關的選項和需求;
TRACE:請求服務器回送收到的請求信息,主要用于測試或診斷;
CONNECT:保留將來使用
缺點:
雖然允許復用TCP連接,但是同一個TCP連接里面,所有的數據通信是按次序進行的。服務器只有處理完一個請求,才會接著處理下一個請求。如果前面的處理特別慢,后面就會有許多請求排隊等著。這將導致“隊頭堵塞”
避免方式:一是減少請求數,二是同時多開持久連接
HTTP/2.0
HTTP?2.0協議是在1.x基礎上的升級而不是重寫,1.x協議的方法,狀態及api在2.0協議里是一樣的。2.0協議重點是對終端用戶的感知延遲、網絡及服務器資源的使用等性能的優化。
特點:
采用二進制格式而非文本格式;
完全多路復用,而非有序并阻塞的、只需一個連接即可實現并行;
使用報頭壓縮,降低開銷
服務器推送
1. 二進制協議
HTTP/1.1 版的頭信息肯定是文本(ASCII編碼),數據體可以是文本,也可以是二進制。HTTP/2 則是一個徹底的二進制協議,頭信息和數據體都是二進制,并且統稱為”幀”:頭信息幀和數據幀。
二進制協議解析起來更高效、“線上”更緊湊,更重要的是錯誤更少。
http2.0之所以能夠突破http1.X標準的性能限制,改進傳輸性能,實現低延遲和高吞吐量,就是因為其新增了二進制分幀層。
在二進制分幀層上,http2.0會將所有傳輸信息分割為更小的消息和幀,并對它們采用二進制格式的編碼將其封裝,新增的二進制分幀層同時也能夠保證http的各種動詞,方法,首部都不受影響,兼容上一代http標準。其中,http1.X中的首部信息header封裝到Headers幀中,而request body將被封裝到Data幀中。如下圖所示:
2. 完全多路復用
HTTP/2 復用TCP連接,在一個連接里,客戶端和瀏覽器都可以同時發送多個請求或回應,而且不用按照順序一一對應,這樣就避免了”隊頭堵塞”。
3. 報頭壓縮
HTTP 協議是沒有狀態,導致每次請求都必須附上所有信息。所以,請求的很多頭字段都是重復的,比如Cookie,一樣的內容每次請求都必須附帶,這會浪費很多帶寬,也影響速度。
對于相同的頭部,不必再通過請求發送,只需發送一次;
HTTP/2 對這一點做了優化,引入了頭信息壓縮機制;
一方面,頭信息使用gzip或compress壓縮后再發送;
另一方面,客戶端和服務器同時維護一張頭信息表,所有字段都會存入這個表,產生一個索引號,之后就不發送同樣字段了,只需發送索引號。
4. 服務器推送
HTTP/2 允許服務器未經請求,主動向客戶端發送資源;
通過推送那些服務器任務客戶端將會需要的內容到客戶端的緩存中,避免往返的延遲。
二、HTTP的請求方式
HTTP主要有8種請求方式,如下所示:
在這8種HTTP請求方式中,GET和POST是最常用的。網頁上的form表單的默認提交方式是GET(在form表單的method屬性不設置時)。
在實際的開發中,我們通常都會使用POST方式發送請求,而不是GET,原因有兩個:
(1)POST傳輸數據大小無限制
(2)POST比GET請求方法更安全:GET請求的參數會在URL地址欄銘文顯示,而POST請求方式傳遞的參數隱藏在實體內容中,用戶看不到。
三、HTTP的請求消息與響應消息
HTTP的請求消息和響應消息是相對應的,都包含三大部分:
HTTP消息除了請求頭和響應頭外,還有一些通用頭字段,如下所示:
三、會話技術
在Web開發中,服務器跟蹤用戶信息的技術成為會話技術。
會話技術有兩種實現:
(1)Cookie:將會話的過程數據保存到用戶瀏覽器上。
(2)Session:?將會話數據保存到服務器端。
Cookie技術
Cookie通過將會話過程的數據保存到用戶的瀏覽器上,使瀏覽器和服務器可以更好地進行數據交互。
我們可以形象的將Cookie理解成我們在商場辦的會員卡。卡上記錄了個人信息、消費額度和積分額度等。以后每次去商場,商場根據會員就能很快了解到顧客的會員信息。
在Cookie模式下,當用戶通過瀏覽器訪問Web服務器時,web服務器會給客戶發送一些信息,這些信息都保存在Cookie中。這樣,當瀏覽器再次訪問服務器時,都會在請求頭中將Cookie發送給服務器,Web服務器端可以分辨出當前請求是由哪個用戶發出的,方便服務器對瀏覽器做出正確的響應,如下圖所示:
為了封裝Cookie信息,前端開發語言必要要有對應的方式。傳統Servlet API會通過javax.servlet.http.Cookie類來實現。里面包含生成Cookie信息和提取Cookie信息的方法。由于現在Servlet已經不再被大量使用,因此我們不展開說明。
JavaScript Cookie的詳細內容,可以看這個鏈接:
https://github.com/js-cookie/js-cookie
需要注意的是,無論瀏覽器是否支持Cookie,用戶第一次訪問程序時,由于服務器不知道客戶瀏覽器是否支持Cookie,在第一次響應的頁面中都會對URL地址進行重寫。如果瀏覽器支持,那么后續的訪問中都會使用Cookie的請求投資端將Session的標識號傳遞給服務器。由此,服務器判斷瀏覽器支持Cookie,后續不再對URL進行重寫。否則后續每個請求的URL都需要進行重寫。
Session技術
Cookie的技術可以將用戶的信息保存在各自的瀏覽器中,并且可以在多次請求下實現數據的共享。但如果傳遞的信息比較多,使用Cookie技術會增大服務器端的程序處理難度。這時,可以使用Session實現,它是一種將會話數據保存到服務器上的技術。
如果形象點說,Session技術就好比醫院發給病人的就醫卡。就醫卡上只有卡號,沒有其他信息,病人去看病時,主要出示就醫卡,醫院就可以根據卡號查到病歷檔案的過程。
當瀏覽器訪問Web服務器時,Servlet容器(還以此舉例)會創建一個Session對象和ID屬性。Session對象相當于病例檔案,ID就相當于就醫卡號。客戶端后續訪問服務器時,只要將標識號傳遞給服務器,服務器就能根據請求是哪個客戶發的,從而選擇與之對應的Session對象為其服務。
需要注意的是:由于客戶端要接受、記錄和發送Session對象的ID,而Session是借助Cookie技術來傳遞ID屬性的。
Session保存用戶信息如下圖所示:
為了方便理解,我們通過兩端代碼分別驗證Cookie和Session的功能。
需求1:設計一個類,使用Cookie技術實現顯示用戶上次訪問時間的功能。
package cn.itcast.chapter06.cookie.example;
import java.io.IOException;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LastAccessServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request,?HttpServletResponse response)throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
/*
* 設定一個 cookie 的name : lastAccessTime
* 讀取客戶端發送cookie 獲得用戶上次的訪問時間顯示*/
String lastAccessTime = null;
// 獲取所有的cookie,并將這些cookie存放在數組中
Cookie[] cookies = request.getCookies();
for (int i = 0; cookies != null && i < cookies.length; i++) {
if ("lastAccess".equals(cookies[i].getName())) {
// 如果cookie的名稱為lastAccess,則獲取該cookie的值
lastAccessTime = cookies[i].getValue();
break;
}
}
// 判斷是否存在名稱為lastAccess的cookie
if (lastAccessTime == null) {
response.getWriter().print("您是首次訪問本站!!!");
} else {
response.getWriter().print("您上次的訪問時間"+lastAccessTime);
}
// 創建cookie,將當前時間作為cookie的值發送給客戶端
Cookie cookie = new Cookie("lastAccess",new Date().toLocaleString());
cookie.setMaxAge(60*60);//保存1小時
//訪問chapter06下資源時回送cookie
cookie.setPath("/chapter06");
// 發送 cookie
response.addCookie(cookie);
}
}
需求2::設計一個類,使用Session技術實現購物車功能。
public class PurchaseServlet extends HttpServlet {
public void doGet(HttpServletRequest req,?HttpServletResponse resp)
throws ServletException, IOException {
// 獲得用戶購買的商品
String id = req.getParameter("id");
if (id == null) {
// 如果id為null,重定向到ListBookServlet頁面
String url = "/chapter06/ListBookServlet";
resp.sendRedirect(url);
return;
}
Book book = BookDB.getBook(id);
// 創建或者獲得用戶的Session對象
HttpSession session = req.getSession();
// 從Session對象中獲得用戶的購物車
List cart = (List)
session.getAttribute("cart");
if (cart == null) {
// 首次購買,為用戶創建一個購物車(List集合模擬購物車)
cart = new ArrayList();
// 將購物城存入Session對象
session.setAttribute("cart", cart);
}
// 將商品放入購物車
cart.add(book);
// 創建Cookie存放Session的標識號
Cookie cookie = new Cookie("JSESSIONID", session.getId());
cookie.setMaxAge(60 * 30);
cookie.setPath("/chapter06");
resp.addCookie(cookie);
// 重定向到購物車頁面
String url = "/chapter06/CartServlet";
resp.sendRedirect(url);
}
}
參考:
《Jva Web程序開發入門》-清華大學出版社
https://zhuanlan.zhihu.com/p/89471776
https://zhuanlan.zhihu.com/p/89471776
總結
以上是生活随笔為你收集整理的http访问不到服务器_HTTP及会话技术解析:大魏Java记4的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 航母在海上容易被发现吗?为什么?
- 下一篇: rip协议中周期性广播路由信息的报文_距