一、HTTP協(xié)議概念
1.1 什么是HTTP協(xié)議
HTTP協(xié)議:瀏覽器客戶端跟服務(wù)器端的數(shù)據(jù)傳輸格式的規(guī)范
2.1 HTTP協(xié)議的內(nèi)容
1.請求(瀏覽器-》服務(wù)器)
GET /day09/hello HTTP/1.1? ? ? ? ? ? //請求行(請求的方式和HTTP版本)
Host: localhost:8080? ? ? ? ? ? ? ? ? ? ? ? //請求頭(ip和端口)
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0? ? //?瀏覽器版本
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8? ? //支持的格式
Accept-Language: zh-cn,en-us;q=0.8,zh;q=0.5,en;q=0.3? ? //支持的文字編碼
Accept-Encoding: gzip, deflate????????
Connection:????keep-alive
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //一個(gè)空行
name=eric&password=123456? ? //實(shí)體內(nèi)容
2.1.1 請求行
HTTP版本:
http1.0:當(dāng)前瀏覽器客戶端與服務(wù)器端建立連接之后,只能發(fā)送一次請求,一次請求之后連接關(guān)閉机蔗。
?http1.1:當(dāng)前瀏覽器客戶端與服務(wù)器端建立連接之后俊马,可以在一次連接中發(fā)送多次請求兵怯。(基本都使用1.1)
請求方式:
基本的請求方式:GET、 POST漠烧、 HEAD杏愤、 TRACE、 PUT沽甥、 CONNECT 声邦、DELETE
常用的請求:POST、GET(常用于表提交)
<form action="提交地址" method="post/get"></form>
POST和GET請求的區(qū)別:
1. GET方式提交:
?????(1)? 地址欄(url)會跟上參數(shù)數(shù)據(jù)摆舟,以?開頭,多個(gè)參數(shù)之間以&分割。
?????(2) GET提交參數(shù)數(shù)據(jù)有限制恨诱,不超過1kb媳瞪。
? ???(3) GET方式不適合提交敏感密碼<密碼,用戶名之類的>照宝。
2.POST方式提交:
? ? (1)?參數(shù)不會跟著url后面蛇受,而是跟在請求的實(shí)體內(nèi)容中。沒有厕鹃?開頭兢仰,多個(gè)參數(shù)之間以&分割。
? ??(2) POST提交的數(shù)據(jù)沒有限制剂碴。
? ??(3) POST提交的數(shù)據(jù)不會暴露把将,適合提交敏感數(shù)據(jù)。
2.1.2 請求頭
Accept: text/html,image/*????? --瀏覽器接受的數(shù)據(jù)類型
Accept-Charset: ISO-8859-1???? --瀏覽器接受的編碼格式
Accept-Encoding: gzip,compress? --瀏覽器接受的數(shù)據(jù)壓縮格式
Accept-Language: en-us,zh-?????? --瀏覽器接受的語言
Host: www.it315.org:80????????? --(必須的)當(dāng)前請求訪問的目標(biāo)地址(主機(jī):端口)
If-Modified-Since: Tue, 11 Jul 2000 18:23:51GMT? --瀏覽器最后的緩存時(shí)間
Referer:http://www.it315.org/index.jsp?? ???--當(dāng)前請求來自于哪里
User-Agent: Mozilla/4.0 (compatible; MSIE5.5; Windows NT 5.0)? --瀏覽器類型
Cookie:name=eric???????????????????? --瀏覽器保存的cookie信息
Connection: close/Keep-Alive? ? --瀏覽器跟服務(wù)器連接狀態(tài)忆矛。close: 連接關(guān)閉? keep-alive:保存連接察蹲。
Date:Tue, 11 Jul 2000 18:23:51 GMT????? --請求發(fā)出的時(shí)間
2.1.2?實(shí)體內(nèi)容
只有POST請求會把數(shù)據(jù)放到實(shí)體內(nèi)容中。
2.1.3 HttpServletRequest對象
HttpServletRequest對象作用是用于獲取請求數(shù)據(jù)催训。
請求行:
request.getMethod(); 請求方式
request.getRequetURI()? 請求資源
request.getProtocol()?? 請求http協(xié)議版本
?請求頭:
request.getHeader("名稱")?? 根據(jù)請求頭獲取請求值
request.getHeaderNames()??? 獲取所有的請求頭名稱
實(shí)體內(nèi)容:????request.getInputStream()??獲取實(shí)體內(nèi)容數(shù)據(jù)
2.2? 什么是時(shí)間戳
概念:很多網(wǎng)站在發(fā)布版本之前洽议,都會在URL請求地址后面加上一個(gè)實(shí)現(xiàn)戳進(jìn)行版本更新(為了防止緩存)
2.3? 防止非法鏈接(referer)
概念:防別的網(wǎng)站直接引用本站的資源(圖片等),引用多了增大服務(wù)器壓力漫拭。
預(yù)防:判斷referer來源亚兄,若請求不是本ip或者綁定的域名,就跳轉(zhuǎn)到警告頁面采驻。
非法鏈接:???????????????????????????????????????????????????????
1)直接訪問訪問資源
?referer:當(dāng)前請求來自于哪里儿捧。
代碼:
??? <filter>
???????? <filter-name>ImgFilter</filter-name>
???????? <filter-class>com.itmayiedu.filter.ImgFilter</filter-class>
??? </filter>
??? <filter-mapping>
???????? <filter-name>ImgFilter</filter-name>
???????? <url-pattern>/static/*</url-pattern>
??? </filter-mapping>
public class ImgFilter implements Filter {
??public void destroy() {
???????? // TODO Auto-generated method stub
?? ?}
?
??? publicvoid doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChainfilterChain)
???????????? throws IOException, ServletException {
???????? HttpServletRequestrequest = (HttpServletRequest) servletRequest;
???????? HttpServletResponseresponse = (HttpServletResponse) servletResponse;
???????? Stringreferer = request.getHeader("referer");
???????? System.out.println("refer is" + "" + referer);
???????? if (referer == null || !referer.contains(request.getServerName())) {
???????????? request.getRequestDispatcher("/static/error.png").forward(request, response);
???????? }else {
???????????? filterChain.doFilter(request, response);
???????? }
??? }
?
??? publicvoid init(FilterConfig arg0) throws ServletException {
???????? // TODO Auto-generated method stub
??? }
}
2.3 傳遞的請求參數(shù)如何獲取?????????
GET方式:參數(shù)放在URI后面
POST方式:參數(shù)放在實(shí)體內(nèi)容中
獲取GET方式參數(shù):request.getQueryString();
獲取POST方式參數(shù):request.getInputStream();
但是以上兩種不通用,而且獲取到的參數(shù)還需要進(jìn)一步地解析挑宠。 所以可以使用統(tǒng)一方便的獲取參數(shù)的方式:
核心的API:
request.getParameter("參數(shù)名");? 根據(jù)參數(shù)名獲取參數(shù)值(注意菲盾,只能獲取一個(gè)值的參數(shù))
request.getParameterValue("參數(shù)名“);根據(jù)參數(shù)名獲取參數(shù)值(可以獲取多個(gè)值的參數(shù))
?request.getParameterNames();??獲取所有參數(shù)名稱列表
3.1 HTTP響應(yīng)
HTTP/1.1 200 OK??????????????? --響應(yīng)行
Server: Apache-Coyote/1.1? --響應(yīng)頭(key-vaule)
Content-Length: 24
Date: Fri, 30 Jan 2015 01:54:57 GMT
?????????????????????????????????????????????? --一個(gè)空行
this is hello servlet? ? ? ? ? ? ? ? ? --實(shí)體內(nèi)容
3.1.1 響應(yīng)行
http協(xié)議版本
狀態(tài)碼: 服務(wù)器處理請求的結(jié)果(狀態(tài))
常見的狀態(tài):
200:表示請求處理完成并完美返回
302:表示請求需要進(jìn)一步細(xì)化各淀。
404 :? 表示客戶訪問的資源找不到懒鉴。
500:表示服務(wù)器的資源發(fā)送錯(cuò)誤。(服務(wù)器內(nèi)部錯(cuò)誤)
狀態(tài)描述?????
3.1.2 常見的響應(yīng)頭
Location:
http://www.it315.org/index.jsp? ? ? ?--表示重定向的地址碎浇,該頭和302的狀態(tài)碼一起使用临谱。
Server:apache tomcat? ? ? ? ? ? ? ? ? ?--表示服務(wù)器的類型
Content-Encoding: gzip? ???????????????--表示服務(wù)器發(fā)送給瀏覽器的數(shù)據(jù)壓縮類型
Content-Length: 80? ? ? ? ? ? ? ? ? ? ? ? --表示服務(wù)器發(fā)送給瀏覽器的數(shù)據(jù)長度
Content-Language: zh-cn? ? ? ? ? ? ? --表示服務(wù)器支持的語言
Content-Type: text/html; charset=GB2312? ? ? ? ? ?--表示服務(wù)器發(fā)送給瀏覽器的數(shù)據(jù)類型及內(nèi)容編碼
Last-Modified: Tue, 11 Jul 2000 18:23:51? GMT? --表示服務(wù)器資源的最后修改時(shí)間
Refresh:1;url=http://www.it315.org? ? ? ? ? ? --表示定時(shí)刷新
Content-Disposition: attachment;filename=aaa.zip --表示告訴瀏覽器以下載方式打開資源(下載文件時(shí)用到)
Transfer-Encoding: chunked
Set-Cookie:SS=Q0=5Lb_nQ; path=/search?? --表示服務(wù)器發(fā)送給瀏覽器的cookie信息(會話管理用到)
Expires: -1?????????????????????????? --表示通知瀏覽器不進(jìn)行緩存
Cache-Control:? no-cache
Pragma: no-cache
Connection: close/Keep-Alive?????????? --表示服務(wù)器和瀏覽器的連接狀態(tài)。close:關(guān)閉連接 keep-alive:保存連接
3.1.3 HttpServletResponse對象
HttpServletResponse對象修改響應(yīng)信息:
響應(yīng)行:response.setStatus()? 設(shè)置狀態(tài)碼
響應(yīng)頭: response.setHeader("name","value")? 設(shè)置響應(yīng)頭
實(shí)體內(nèi)容:response.getWriter().writer();?? 發(fā)送字符實(shí)體內(nèi)容
? ? ? ? ? ? ? ? ? response.getOutputStream().writer()? 發(fā)送字節(jié)實(shí)體內(nèi)容
3.1.4? ?請求重定向(本服務(wù)器)
resp.setStatus(302);
resp.setHeader("Location", "OtherServlet");//重定向到別的服務(wù)器
4.1Https與Http
4.1.1 https與http區(qū)別奴璃?
1悉默、https 協(xié)議需要到 ca 申請證書,一般免費(fèi)證書較少苟穆,因而需要一定費(fèi)用抄课。
2唱星、http 是超文本傳輸協(xié)議,信息是明文傳輸跟磨,https則是具有安全性的ssl 加密傳輸協(xié)議间聊。
3、http 和 https 使用的是完全不同的連接方式抵拘,用的端口也不一樣哎榴,前者是80,后者是 443僵蛛。
4尚蝌、http 的連接很簡單,是無狀態(tài)的充尉;HTTPS協(xié)議是由SSL+HTTP 協(xié)議構(gòu)建的可進(jìn)行加密傳輸飘言、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議,比http 協(xié)議安全喉酌。
4.1.2 https工作原理热凹?
我們都知道HTTPS 能夠加密信息,以免敏感信息被第三方獲取泪电,所以很多銀行網(wǎng)站或電子郵箱等等安全級別較高的服務(wù)都會采用HTTPS 協(xié)議般妙。客戶端在使用HTTPS 方式與Web 服務(wù)器通信時(shí)有以下幾個(gè)步驟相速,如圖所示碟渺。(1)客戶使用 https 的 URL 訪問 Web 服務(wù)器,要求與 Web 服務(wù)器建立 SSL 連接突诬。
(2)Web 服務(wù)器收到客戶端請求后苫拍,會將網(wǎng)站的證書信息(證書中包含公鑰)傳送一份給客戶端。
(3)客戶端的瀏覽器與 Web 服務(wù)器開始協(xié)商 SSL 連接的安全等級旺隙,也就是信息加密的等級绒极。
(4)客戶端的瀏覽器根據(jù)雙方同意的安全等級,建立會話密鑰蔬捷,然后利用網(wǎng)站的公鑰將會話密鑰加密垄提,并傳送給網(wǎng)站。
(5)Web 服務(wù)器利用自己的私鑰解密出會話密鑰周拐。
(6)Web 服務(wù)器利用會話密鑰加密與客戶端之間的通信铡俐。
4.1.3 https優(yōu)缺點(diǎn)?
雖然說HTTPS 有很大的優(yōu)勢妥粟,但其相對來說审丘,還是存在不足之處的:
(1)HTTPS 協(xié)議握手階段比較費(fèi)時(shí),會使頁面的加載時(shí)間延長近50%勾给,增加 10% 到 20% 的耗電滩报;
(2)HTTPS 連接緩存不如 HTTP 高效锅知,會增加數(shù)據(jù)開銷和功耗,甚至已有的安全措施也會因此而受到影響露泊;
(3)SSL 證書需要錢喉镰,功能越強(qiáng)大的證書費(fèi)用越高旅择,個(gè)人網(wǎng)站惭笑、小網(wǎng)站沒有必要一般不會用。
(4)SSL 證書通常需要綁定 IP生真,不能在同一 IP 上綁定多個(gè)域名沉噩,IPv4 資源不可能支撐這個(gè)消耗。
(5)HTTPS 協(xié)議的加密范圍也比較有限柱蟀,在黑客攻擊川蒙、拒絕服務(wù)攻擊、服務(wù)器劫持等方面幾乎起不到什么作用长已。最關(guān)鍵的畜眨,SSL證書的信用鏈體系并不安全,特別是在某些國家可以控制CA 根證書的情況下术瓮,中間人攻擊一樣可行康聂。
5.1 跨域?qū)崙?zhàn)解決方案
跨域原因產(chǎn)生:在當(dāng)前域名請求網(wǎng)站中,默認(rèn)不允許通過ajax請求發(fā)送其他域名胞四。
報(bào)錯(cuò)信息:XMLHttpRequest cannot load
5.1.1?使用后臺response添加header解決
后臺response添加header恬汁,response.setHeader("Access-Control-Allow-Origin","*");支持所有網(wǎng)站
前端代碼:
$.ajax({
???????????? type? :"POST",
???????????? async? :false,
???????????? url :"http://a.a.com/a/FromUserServlet?userName=張三",
???????????? dataType? :"jsonp",//數(shù)據(jù)類型為jsonp?
???????????? jsonp? :"jsonpCallback",//服務(wù)端用于接收callback調(diào)用的function名的參數(shù)
???????????? success? :function(data) {
????????????????? alert(data.result);
???????????? },
???????????? error? :function() {
????????????????? alert('fail');
???????????? }
???????? });
后端代碼:
@WebServlet("/FromUserServlet")
publicclassFromUserServletextends HttpServlet {
?
??? @Override
??? protectedvoid doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
???????? doPost(req, resp);
??? }
?
??? @Override
??? protectedvoid doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
???????? resp.setCharacterEncoding("UTF-8");
???????? //
? resp.setHeader("Access-Control-Allow-Origin", "*");
???????? ?StringuserName = req.getParameter("userName");
???????? ?StringuserAge = req.getParameter("userAge");
???????? ?System.out.println(userName + "----" + userAge+"---"+req.getMethod());
???????? // JSONObject
? JSONObject1 = new JSONObject();
???????? //
? JSONObject1.put("success", "添加成功!");
???????? //? resp.getWriter().write("callbackparam(" +? JSONObject1.toJSONString()
???????? // + ")");
?
???????? try {
???????????? resp.setContentType("text/plain");
???????????? resp.setHeader("Pragma", "No-cache");
???????????? resp.setHeader("Cache-Control", "no-cache");
???????????? resp.setDateHeader("Expires", 0);
???????????? PrintWriterout = resp.getWriter();
???????????? JSONObjectresultJSON = new JSONObject(); // 根據(jù)需要拼裝json
???????????? resultJSON.put("result", "content");
???????????? StringjsonpCallback = req.getParameter("jsonpCallback");// 客戶端請求參數(shù)
???????????? out.println(jsonpCallback + "(" + resultJSON.toJSONString() + ")");// 返回jsonp格式數(shù)據(jù)
???????????? out.flush();
???????????? out.close();
???????? }catch (Exception e) {
???????????? // TODO: handle exception
???????? }
??? }
}
JSONP的優(yōu)缺點(diǎn):
JSONP只支持get請求不支持psot請求
5.1.2 使用接口網(wǎng)關(guān)
5.1.3 使用nginx轉(zhuǎn)發(fā)?
http 常用的狀態(tài)碼
200 表示成功
301 Moved Permanently 永久重定向。http 轉(zhuǎn)向 https時(shí)辜伟,有時(shí)會使用 301氓侧,如B站. 請求的 URL已移走。Response 中應(yīng)該包含一個(gè) Location URL, 說明資源現(xiàn)在所處的位置
302 暫時(shí)重定向导狡。http 轉(zhuǎn)向 https時(shí)约巷,有時(shí)也會使用 302,如知乎
400 Bad Request 客戶端請求有語法錯(cuò)誤旱捧,不能被服務(wù)器所理解
401 Unauthorized 當(dāng)沒有權(quán)限的用戶請求需要帶有權(quán)限的資源時(shí)独郎,會返回 401,此時(shí)攜帶正確的權(quán)限憑證再試一次可以解決問題
403 Forbidden 服務(wù)器收到請求廊佩,但是拒絕提供服務(wù)
404 Not Found 請求資源不存在囚聚,eg:輸入了錯(cuò)誤的 URL
500 Internal Server Error 服務(wù)器內(nèi)部錯(cuò)誤,很有可能是應(yīng)用層未捕獲錯(cuò)誤而導(dǎo)致整個(gè)服務(wù)掛掉
503 Server Unavailable 服務(wù)器當(dāng)前不能處理客戶端的請求标锄,一段時(shí)間后可能恢復(fù)正常