耦合性:也稱塊間聯繫。指軟件系統結構中各模塊間相互聯繫緊密程度的一種度量。模塊之間聯繫越緊密,其耦合性就越強,模塊的獨立性則越差。模塊間耦合高低取決於模塊間接口的複雜性、調用的方式及傳遞的信息css
內聚性:又稱塊內聯繫。指模塊的功能強度的度量,即一個模塊內部各個元素彼此結合的緊密程度的度量。若一個模塊內各元素(語名之間、程序段之間)聯繫的越緊密,則它的內聚性就越高。html
應用層:是體系結構中的最高。直接爲用戶的應用進程提供服務。在因特網中的應用層協議不少,如支持萬維網應用的HTTP協議,支持電子郵件的SMTP協議,支持文件傳送的FTP協議等等。html5
運輸層:運輸層主要使用如下兩種協議:
(1) 傳輸控制協議TCP(Transmission Control Protocol):面向鏈接的,數據傳輸的單位是報文段,可以提供可靠的交付。
(2) 用戶數據包協議UDP(User Datagram Protocol):無鏈接的,數據傳輸的單位是用戶數據報,不保證提供可靠的交付,只能提供「盡最大努力交付」。linux
網絡層:負責爲分組交換網上的不一樣主機提供通訊服務。在發送數據時,網絡層把運輸層殘生的報文段或用戶數據報封裝成分組或包進行傳送。在TCP/IP體系中,因爲網絡層使用IP協議,所以分組也叫作IP數據報,或簡稱爲數據報。css3
數據鏈路層:網橋(現已不多使用)、以太網交換機(二層交換機)、網卡(其實網卡 是一半工做在物理層、一半工做在數據鏈路層)nginx
物理層:在物理層上所傳數據的單位是比特。物理層的任務就是透明地傳送比特流。git
所謂的「三次握手」即對每次發送的數據量是怎樣跟蹤進行協商使數據段的發送和接收同步,根據所接收到的數據量而肯定的數據確認數及數據發送、接收完畢後什麼時候撤消聯繫,並創建虛鏈接。github
第一次握手:創建鏈接時,客戶端發送syn包(syn=j)到服務器,並進入SYN_SENT狀態,等待服務器確認;SYN:同步序列編號(Synchronize Sequence Numbers)。web
第二次握手:服務器收到syn包,必須確認客戶的SYN(ack=j+1),同時本身也發送一個SYN包(syn=k),即SYN+ACK包,此時服務器進入SYN_RECV狀態;面試
第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=k+1),此包發送完畢,客戶端和服務器進入ESTABLISHED(TCP鏈接成功)狀態,完成三次握手。
協議是指計算機通訊網絡中兩臺計算機之間進行通訊所必須共同遵照的規定或規則,超文本傳輸協議(HTTP)是一種通訊協議,它容許將超文本標記語言(HTML)文檔從Web服務器傳送到客戶端的瀏覽器。
HTTP協議,即超文本傳輸協議(Hypertext transfer protocol)。是一種詳細規定了瀏覽器和萬維網(WWW = World Wide Web)服務器之間互相通訊的規則,經過因特網傳送萬維網文檔的數據傳送協議。
HTTP協議是用於從WWW服務器傳輸超文本到本地瀏覽器的傳送協議。它可使瀏覽器更加高效,使網絡傳輸減小。它不只保證計算機正確快速地傳輸超文本文檔,還肯定傳輸文檔中的哪一部分,以及哪部份內容首先顯示(如文本先於圖形)等。
HTTP是一個應用層協議,由請求和響應構成,是一個標準的客戶端服務器模型。HTTP是一個無狀態的協議。
在Internet中全部的傳輸都是經過TCP/IP進行的。HTTP協議做爲TCP/IP模型中應用層的協議也不例外。HTTP協議一般承載於TCP協議之上,有時也承載於TLS或SSL協議層之上,這個時候,就成了咱們常說的HTTPS。以下圖所示:(SSL(Secure Sockets Layer 安全套接層),及其繼任者傳輸層安全(Transport Layer Security,TLS)是爲網絡通訊提供安全及數據完整性的一種安全協議。TLS與SSL在傳輸層對網絡鏈接進行加密。)
HTTP默認的端口號爲80,HTTPS的端口號爲443。
瀏覽網頁是HTTP的主要應用,可是這並不表明HTTP就只能應用於網頁的瀏覽。HTTP是一種協議,只要通訊的雙方都遵照這個協議,HTTP就能有用武之地。好比我們經常使用的QQ,迅雷這些軟件,都會使用HTTP協議(還包括其餘的協議)。
2、簡史
它的發展是萬維網協會(World Wide Web Consortium)和Internet工做小組IETF(Internet Engineering Task Force)合做的結果,(他們)最終發佈了一系列的RFC,RFC 1945定義了HTTP/1.0版本。其中最著名的就是RFC 2616。RFC 2616定義了今天廣泛使用的一個版本——HTTP 1.1。
3、特色
HTTP協議永遠都是客戶端發起請求,服務器回送響應。這樣就限制了使用HTTP協議,沒法實如今客戶端沒有發起請求的時候,服務器將消息推送給客戶端。
HTTP協議的主要特色可歸納以下:
1、支持客戶/服務器模式。支持基本認證和安全認證。
2、簡單快速:客戶向服務器請求服務時,只需傳送請求方法和路徑。請求方法經常使用的有GET、HEAD、POST。每種方法規定了客戶與服務器聯繫的類型不一樣。因爲HTTP協議簡單,使得HTTP服務器的程序規模小,於是通訊速度很快。
3、靈活:HTTP容許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type加以標記。
4、HTTP 0.9和1.0使用非持續鏈接:限制每次鏈接只處理一個請求,服務器處理完客戶的請求,並收到客戶的應答後,即斷開鏈接。HTTP 1.1使用持續鏈接:沒必要爲每一個web對象建立一個新的鏈接,一個鏈接能夠傳送多個對象,採用這種方式能夠節省傳輸時間。
5、無狀態:HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺乏狀態意味着若是後續處理須要前面的信息,則它必須重傳,這樣可能致使每次鏈接傳送的數據量增大。
無狀態協議:
協議的狀態是指下一次傳輸能夠「記住」此次傳輸信息的能力。
http是不會爲了下一次鏈接而維護此次鏈接所傳輸的信息,爲了保證服務器內存。
好比客戶得到一張網頁以後關閉瀏覽器,而後再一次啓動瀏覽器,再登錄該網站,可是服務器並不知道客戶關閉了一次瀏覽器。
因爲Web服務器要面對不少瀏覽器的併發訪問,爲了提升Web服務器對併發訪問的處理能力,在設計HTTP協議時規定Web服務器發送HTTP應答報文和文檔時,不保存發出請求的Web瀏覽器進程的任何狀態信息。這有可能出現一個瀏覽器在短短几秒以內兩次訪問同一對象時,服務器進程不會由於已經給它發過應答報文而不接受第二期服務請求。因爲Web服務器不保存發送請求的Web瀏覽器進程的任何信息,所以HTTP協議屬於無狀態協議(Stateless Protocol)。
HTTP協議是無狀態的和Connection: keep-alive的區別:
無狀態是指協議對於事務處理沒有記憶能力,服務器不知道客戶端是什麼狀態。從另外一方面講,打開一個服務器上的網頁和你以前打開這個服務器上的網頁之間沒有任何聯繫。
HTTP是一個無狀態的面向鏈接的協議,無狀態不表明HTTP不能保持TCP鏈接,更不能表明HTTP使用的是UDP協議(無鏈接)。
從HTTP/1.1起,默認都開啓了Keep-Alive,保持鏈接特性,簡單地說,當一個網頁打開完成後,客戶端和服務器之間用於傳輸HTTP數據的TCP鏈接不會關閉,若是客戶端再次訪問這個服務器上的網頁,會繼續使用這一條已經創建的鏈接。
Keep-Alive不會永久保持鏈接,它有一個保持時間,能夠在不一樣的服務器軟件(如Apache)中設定這個時間。
4、工做流程
一次HTTP操做稱爲一個事務,其工做過程可分爲四步:
1)首先客戶機與服務器須要創建鏈接。只要單擊某個超級連接,HTTP的工做開始。
2)創建鏈接後,客戶機發送一個請求給服務器,請求方式的格式爲:統一資源標識符(URL)、協議版本號,後邊是MIME信息包括請求修飾符、客戶機信息和可能的內容。
3)服務器接到請求後,給予相應的響應信息,其格式爲一個狀態行,包括信息的協議版本號、一個成功或錯誤的代碼,後邊是MIME信息包括服務器信息、實體信息和可能的內容。
4)客戶端接收服務器所返回的信息經過瀏覽器顯示在用戶的顯示屏上,而後客戶機與服務器斷開鏈接。
若是在以上過程當中的某一步出現錯誤,那麼產生錯誤的信息將返回到客戶端,有顯示屏輸出。對於用戶來講,這些過程是由HTTP本身完成的,用戶只要用鼠標點擊,等待信息顯示就能夠了。
HTTP是基於傳輸層的TCP協議,而TCP是一個端到端的面向鏈接的協議。所謂的端到端能夠理解爲進程到進程之間的通訊。因此HTTP在開始傳輸以前,首先須要創建TCP鏈接,而TCP鏈接的過程須要所謂的「三次握手」。下圖所示TCP鏈接的三次握手。
在TCP三次握手以後,創建了TCP鏈接,此時HTTP就能夠進行傳輸了。一個重要的概念是面向鏈接,既HTTP在傳輸完成之間並不斷開TCP鏈接。在HTTP1.1中(經過Connection頭設置)這是默認行爲。
100-199:表示信息性代碼,標示客戶端應該採起的其餘動做,請求正在進行。
200-299:表示客戶請求成功。
300-399:表示用於已經移走的資源文件,指示新的地址。 重定向
400-499:表示由客戶端引起的錯誤。
500-599:表示由服務器端引起的錯誤。
404 沒找到頁面(not found)
403 禁止訪問(forbidden)
200 一切正常(ok)
302/307 臨時重定向
301 永久重定向
304 沒有被修改(not modified)(服務器返回304狀態,表示源文件沒有被修改)從緩存中讀取
按照響應信息的格式,先有狀態行,再有消息體,因此注意在使用PrintWriter向客戶端輸出信息以前,設置狀態碼
設置HTTP響應頭
目的用於告訴客戶端
發送回來的內容的類型
有多少內容被正被髮送
發送內容的服務器的類型
設置響應頭的方法:setHeader()或setHeaders()。注意:設置響應頭只能是HTTP協議。因此setHeader和setHeaders()都是HttpServletResponse中的方法
設置HTTP消息體
response.getWriter()得到打印字符流,能夠輸出文本
response.getOutputStream()得到輸出字節流,能夠發送二進制數據。
重定向調用方法:
response.sendRedirect(「http://127.0.0.1:8080/lovobook/bar.html「);
1,
瀏覽器向服務器發送HTTP請求。
2,服務器接收到請求後,若是調用response.sendRedirect()方法,表示資源已被移走。則發送一個302的狀態碼和location的響應頭。在location響應頭指明要轉發的地址。 302:臨時重定向
3,瀏覽器在接收到302狀態碼後,會讀取location響應頭的內容,並將地址欄的值賦爲location響應頭的內容。從而再向服務器發出第二次請求。因爲是二次請求,因此重定向不能得到封裝在request中的屬性信息
轉發是服務器行爲,重定向是客戶端行爲
轉發的速度快;重定向速度慢
一、 內部轉發由requestDispatcher發出,重定向由response發出。
二、內部轉發是一次請求,重定向是兩次不一樣請求。
三、內部轉發能夠取出request中封裝的數據(攜帶參數),重定向不能。
四、 轉發地址欄沒有變化,重定向地址欄有變化
5、內部轉發只能在服務器內部進行,重定向能夠請求別的服務器。
五、 轉發不會執行轉發後的代碼,重定向會執行重定向以後的代碼
在servlet中調用轉發、重定向的語句以下:
//轉發到
request.getRequestDispatcher("new.jsp").forward(request, response);
//重定向
response.sendRedirect("new.jsp");
在controller層轉發、重定向語句以下:
//轉發
@RequestMapping("/index")
public String index(){
//some code
return "index/index"; //默認是轉發,不會顯示轉發路徑
}
@RequestMapping("/index")
public ModelAndView index(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("index/index"); //默認轉發,跳到此頁面
return modelAndView;
}
上述轉發的路徑是轉發到存放jsp頁面的路徑,就是index文件夾下的index.jsp。
但若是加上forward,
就是轉發到controller層的控制類下的方法(命名空間/RequestMapping)
return "forward:index/index";
modelAndView.setViewName("forward:index/index");
//重定向 (加上redirect)
@RequestMapping("/index")
public String index(){
//some code
return "redirect:index/index"; //地址欄顯示重定向路徑
}
@RequestMapping("/index")
public ModelAndView index(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("redirect:index/index");
return modelAndView;
}
轉發過程:客戶瀏覽器發送http請求,web服務器接受此請求,調用內部的一個方法在容器內部完成請求處理和轉發動做,將目標資源發送給客戶;在這裏,轉發的路徑必須是同一個web容器下的url,其不能轉向到其餘的web路徑上去,中間傳遞的是本身的容器內的request。在客戶瀏覽器路徑欄顯示的仍然是其第一次訪問的路徑,也就是說客戶是感受不到服務器作了轉發的。轉發行爲是瀏覽器只作了一次訪問請求。
重定向過程:客戶瀏覽器發送http請求,web服務器接受後發送302狀態碼響應及對應新的location給客戶瀏覽器,客戶瀏覽器發現是302響應,則自動再發送一個新的http請求,請求url是新的location地址,服務器根據此請求尋找資源併發送給客戶。在這裏location能夠重定向到任意URL,既然是瀏覽器從新發出了請求,則就沒有什麼request傳遞的概念了。在客戶瀏覽器路徑欄顯示的是其重定向的路徑,客戶能夠觀察到地址的變化的。重定向行爲是瀏覽器作了至少兩次的訪問請求的。
重定向,實際上是兩次request
第一次,客戶端request A,服務器響應,並response回來,告訴瀏覽器,你應該去B。這個時候IE能夠看到地址變了,並且歷史的回退按鈕也亮了。重定向能夠訪問本身web應用之外的資源。在重定向的過程當中,傳輸的信息會被丟失。
在翻譯好的類中,在_jspService()中有九個局部變量,並都作了初始化。因爲咱們在JSP中書寫的內容都是豐富_jspService()方法,因此能夠直接使用這些局部變量,這就是隱式對象
四個做用域:
page:在一個頁面內保存屬性,跳轉以後無效。page對象表明JSP自己,只有在JSP頁面內纔是合法的。
request:做用於請求 :在一次服務請求範圍內,服務器跳轉後依然有效,request對象表明了客戶端的請求信息,主要用於接受經過HTTP協議傳送到服務器的數據
session:做用於會話 :在一次會話範圍內,不管何種跳轉均可以使用,可是關閉瀏覽器後,新開瀏覽器沒法使用。session對象是由服務器自動建立的與用戶請求相關的對象。服務器爲每一個用戶都生成一個session對象,用於保存該用戶的信息,跟蹤用戶的操做狀態
application:做用於全局(類型是ServletContext) :整個服務器上保存,全部用戶均可以使用。application對象可將信息保存在服務器中,直到服務器關閉,不然application對象中保存的信息會在整個應用中都有效
response:表明的是對客戶端的響應,主要是將JSP容器處理過的對象傳回到客戶端
out:對象用於在Web瀏覽器內輸出信息,而且管理應用服務器上的輸出緩衝區pageContext 對象的做用是取得任何範圍的參數
config:對象的主要做用是取得服務器的配置信息
exception:對象的做用是顯示異常信息
事務在英文中是transaction,和現實世界中的交易很相似,它有以下四個特性:
事務的特性:
1、A (Atomicity) 原子性
原子性很容易理解,也就是說事務裏的全部操做要麼所有作完,要麼都不作,事務成功的條件是事務裏的全部操做都成功,只要有一個操做失敗,整個事務就失敗,須要回滾。
好比銀行轉帳,從A帳戶轉100元至B帳戶,分爲兩個步驟:1)從A帳戶取100元;2)存入100元至B帳戶。這兩步要麼一塊兒完成,要麼一塊兒不完成,若是隻完成第一步,第二步失敗,錢會莫名其妙少了100元。
2、C (Consistency) 一致性
一致性也比較容易理解,也就是說數據庫要一直處於一致的狀態,事務的運行不會改變數據庫本來的一致性約束。
例如現有完整性約束a+b=10,若是一個事務改變了a,那麼必須得改變b,使得事務結束後依然知足a+b=10,不然事務失敗。
3、I (Isolation) 獨立性
所謂的獨立性是指併發的事務之間不會互相影響,若是一個事務要訪問的數據正在被另一個事務修改,只要另一個事務未提交,它所訪問的數據就不受未提交事務的影響。
好比如今有個交易是從A帳戶轉100元至B帳戶,在這個交易還未完成的狀況下,若是此時B查詢本身的帳戶,是看不到新增長的100元的。
4、D (Durability) 持久性
持久性是指一旦事務提交後,它所作的修改將會永久的保存在數據庫上,即便出現宕機也不會丟失。
1.因爲HTTP協議是無狀態的協議,因此服務端須要記錄用戶的狀態時,就須要用某種機制來識具體的用戶,這個機制就是Session.典型的場景好比購物車,當你點擊下單按鈕時,因爲HTTP協議無狀態,因此並不知道是哪一個用戶操做的,因此服務端要爲特定的用戶建立了特定的Session,用用於標識這個用戶,而且跟蹤用戶,這樣才知道購物車裏面有幾本書。這個Session是保存在服務端的,有一個惟一標識。在服務端保存Session的方法不少,內存、數據庫、文件都有。集羣的時候也要考慮Session的轉移,在大型的網站,通常會有專門的Session服務器集羣,用來保存用戶會話,這個時候 Session 信息都是放在內存的,使用一些緩存服務好比Memcached之類的來放 Session。
2. 思考一下服務端如何識別特定的客戶?這個時候Cookie就登場了。每次HTTP請求的時候,客戶端都會發送相應的Cookie信息到服務端。實際上大多數的應用都是用 Cookie 來實現Session跟蹤的,第一次建立Session的時候,服務端會在HTTP協議中告訴客戶端,須要在 Cookie 裏面記錄一個Session ID,之後每次請求把這個會話ID發送到服務器,我就知道你是誰了。有人問,若是客戶端的瀏覽器禁用了 Cookie 怎麼辦?通常這種狀況下,會使用一種叫作URL重寫的技術來進行會話跟蹤,即每次HTTP交互,URL後面都會被附加上一個諸如 sid=xxxxx 這樣的參數,服務端據此來識別用戶。
3. Cookie其實還能夠用在一些方便用戶的場景下,設想你某次登錄過一個網站,下次登陸的時候不想再次輸入帳號了,怎麼辦?這個信息能夠寫到Cookie裏面,訪問網站的時候,網站頁面的腳本能夠讀取這個信息,就自動幫你把用戶名給填了,可以方便一下用戶。這也是Cookie名稱的由來,給用戶的一點甜頭。
Session是在服務端保存的一個數據結構,用來跟蹤用戶的狀態,這個數據能夠保存在集羣、數據庫、文件中;
Cookie是客戶端保存用戶信息的一種機制,用來記錄用戶的一些信息,也是實現Session的一種方式。存儲量過小,只有 4KB
Expires是Web服務器響應消息頭字段,在響應http請求時告訴瀏覽器在過時時間前瀏覽器能夠直接從瀏覽器緩存取數據,而無需再次請求。
注:Date頭域表示消息發送的時間,時間的描述格式由rfc822定義。例如,Date: Mon,31 Dec 2001 04:25:57GMT。
Web服務器告訴瀏覽器在2012-11-28 03:30:01這個時間點以前,可使用緩存文件。發送請求的時間是2012-11-28 03:25:01,即緩存5分鐘。
不過Expires 是HTTP 1.0的東西,如今默認瀏覽器均默認使用HTTP 1.1,因此它的做用基本忽略。
Cache-Control與Expires的做用一致,都是指明當前資源的有效期,控制瀏覽器是否直接從瀏覽器緩存取數據仍是從新發請求到服務器取數據。只不過Cache-Control的選擇更多,設置更細緻,若是同時設置的話,其優先級高於Expires。
http協議頭Cache-Control : |
值能夠是public、private、no-cache、no- store、no-transform、must-revalidate、proxy-revalidate、max-age 各個消息中的指令含義以下:
|
仍是上面那個請求,web服務器返回的Cache-Control頭的值爲max-age=300,即5分鐘(和上面的Expires時間一致,這個不是必須的)。
Last-Modified/If-Modified-Since要配合Cache-Control使用。
l Last-Modified:標示這個響應資源的最後修改時間。由服務器往客戶端發送的http頭,web服務器在響應請求時,告訴瀏覽器資源的最後修改時間。
l If-Modified-Since:響應資源最後修改的時間,由客戶端往服務端發送的頭。再次請求本地存在的 cache 頁面時,客戶端會經過 If-Modified-Since 頭將先前服務器端發過來的 Last-Modified 最後修改時間戳發送回去,這是爲了讓服務器端進行驗證,經過這個時間戳判斷客戶端的頁面是不是最新的,若是不是最新的,則返回200,返回新的內容。若是是最新的,則 返回 304 告訴客戶端其本地 cache 的頁面是最新的,因而客戶端就能夠直接從本地加載頁面了,這樣在網絡上傳輸的數據就會大大減小,同時也減輕了服務器的負擔。
Etag/If-None-Match也要配合Cache-Control使用。
l Etag:服務端往客服端發送的頭。web服務器響應請求時,告訴瀏覽器當前資源在服務器的惟一標識(生成規則由服務器決定)。Apache中,ETag的值,默認是對文件的索引節(INode),大小(Size)和最後修改時間(MTime)進行Hash後獲得的。
l If-None-Match:(Etags的值),客戶端往服務端發送的頭。工做原理是在HTTP Response中添加ETags信息。當客戶端再次請求該資源時,將在HTTP Request中加入If-None-Match信息(ETags的值)。若是服務器驗證資源的ETags沒有改變(該資源沒有改變),將返回一個304狀態;不然,服務器將返回200狀態,並返回該資源和新的ETags。
你可能會以爲使用Last-Modified已經足以讓瀏覽器知道本地的緩存副本是否足夠新,爲何還須要Etag(實體標識)呢?HTTP1.1中Etag的出現主要是爲了解決幾個Last-Modified比較難解決的問題:
l Last-Modified標註的最後修改只能精確到秒級,若是某些文件在1秒鐘之內,被修改屢次的話,它將不能準確標註文件的修改時間
l 若是某些文件會被按期生成,當有時內容並無任何變化,但Last-Modified卻改變了,致使文件無法使用緩存
l 有可能存在服務器沒有準確獲取文件修改時間,或者與代理服務器時間不一致等情形
Etag是服務器自動生成或者由開發者生成的對應資源在服務器端的惟一標識符,可以更加準確的控制緩存。Last-Modified與ETag是能夠一塊兒使用的,服務器會優先驗證ETag,一致的狀況下,纔會繼續比對Last-Modified,最後才決定是否返回304。
瀏覽器緩存行爲還有用戶的行爲有關!!!
用戶操做 |
Expires/Cache-Control |
Last-Modified/Etag |
地址欄回車 |
有效 |
有效 |
頁面連接跳轉 |
有效 |
有效 |
新開窗口 |
有效 |
有效 |
前進、後退 |
有效 |
有效 |
F5刷新 |
無效 |
有效 |
Ctrl+F5刷新 |
無效 |
無效 |
統一資源標誌符URI:就是在某一規則下能把一個資源獨一無二地標識出來。
拿人作例子,身份證號就是URI,經過身份證號能讓咱們能且僅能肯定一我的。
統一資源定位符URL:也拿人作例子:動物住址協議://地球/中國/浙江省/杭州市/西湖區/某大學/14號宿舍樓/525號寢/張三.人
能夠看到,這個字符串一樣標識出了惟一的一我的,起到了URI的做用,因此URL是URI的子集。URL是以描述資源的位置來惟一肯定一個資源的。
因此不管是用定位的方式仍是用編號的方式,咱們均可以惟一肯定一我的,都是URl的一種實現,而URL就是用定位的方式實現的URI。
回到Web上,假設全部的Html文檔都有惟一的編號,記做html:xxxxx,xxxxx是一串數字,即Html文檔的身份證號碼,這個能惟一標識一個Html文檔,那麼這個號碼就是一個URI。
而URL則經過描述是哪一個主機上哪一個路徑上的文件來惟一肯定一個資源,也就是定位的方式來實現的URI。
事件傳播的順序對應瀏覽器的兩種事件流模型:捕獲型事件流和冒泡型事件流。
DOM標準採用捕獲+冒泡。兩種事件流都會觸發DOM的全部對象,從document對象開始,也在document對象結束。
DOM標準規定事件流包括三個階段:事件捕獲階段、處於目標階段和事件冒泡階段。
事件捕獲階段:實際目標(<div>)在捕獲階段不會接收事件。也就是在捕獲階段,事件從document到<html>再到<body>就中止了。上圖中爲1~3.
處於目標階段:事件在<div>上發生並處理。可是事件處理會被當作是冒泡階段的一部分。上圖中爲4
冒泡階段:事件又傳播迴文檔。上圖中爲5~7
阻止事件冒泡:
如有一a標籤:
<a href="http://www.baidu.com" target="_blank"></a>
1.event.stopPropagation()方法
這是阻止事件的冒泡方法,不讓事件向documen上蔓延,可是默認事件任然會執行,當你掉用這個方法的時候,若是點擊一個鏈接,這個鏈接仍然會被打開,不會冒泡到父元素直至document
2.event.preventDefault()方法
這是阻止默認事件的方法,調用此方法是,鏈接不會被打開,可是會發生冒泡,冒泡會傳遞到上一層的父元素;
3.return false ;
這個方法比較暴力,他會同時阻止事件冒泡也會阻止默認事件;寫上此代碼,鏈接不會被打開,事件也不會傳遞到上一層的父元素;能夠理解爲return false就等於同時調用了event.stopPropagation()和event.preventDefault(),但能夠在return false以前執行一些必要代碼。但標籤內部的事件不會執行
瞭解同源政策:所謂"同源"指的是"三個相同"。
設想這樣一種狀況:A網站是一家銀行,用戶登陸之後,又去瀏覽其餘網站。若是其餘網站能夠讀取A網站的 Cookie,會發生什麼?
很顯然,若是 Cookie 包含隱私(好比存款總額),這些信息就會泄漏。更可怕的是,Cookie 每每用來保存用戶的登陸狀態,若是用戶沒有退出登陸,其餘網站就能夠冒充用戶,隨心所欲。由於瀏覽器同時還規定,提交表單不受同源政策的限制。
因而可知,"同源政策"是必需的,不然 Cookie 能夠共享,互聯網就毫無安全可言了。
首先假設你請求數據的網站爲B。要看你是否能夠控制(修改裏面的代碼)。
1 jsonp 缺點:只能get請求 ,須要修改B網站的代碼
2 cors 這個方案缺點 是 ie6 7 兼容很差(卻是不見得要兼容)。須要B網站在響應中加頭
3 postMessage 缺點也是 ie6 7 兼容很差(卻是不見得要兼容)。須要修改B網站的代碼
4 iframe window.name 傳值得方式很巧妙,兼容性也很好。可是也是須要你能修改B網站代碼
5 服務端主動請求B網站,兼容性好並且你客戶端的代碼仍是原來的ajax,缺點是感受很差。(服務器端是不存在跨域安全限制的)
6 相似5 用nginx把B網站的數據url反向代理。
若是你不能修改B網站的代碼老老實實5 6 方案
若是能修改B網站 方案2的修改應該是最簡單的。
就算是B網站你能夠修改,還有種需求處理起來比較麻煩的,就是有的數據須要登陸以後才能取。
最直接的方案,B網站提供數據的url 進去先提供用戶名密碼,走下登陸再走取數據,最後返回數據。
Jsonp解決跨域:
1 $.ajax({ 2 3 url:url, 4 5 dataType:'jsonp', 6 7 processData: false, 8 9 type:'get', 10 11 success:function(data){ 12 13 alert(data.name); 14 15 }, 16 17 error:function(XMLHttpRequest, textStatus, errorThrown) { 18 19 alert(XMLHttpRequest.status); 20 21 alert(XMLHttpRequest.readyState); 22 23 alert(textStatus); 24 25 } 26 27 });
jsonp其實返回的是一個JS函數調用代碼,把返回的數據和客戶端能調用的函數名拼接在一塊兒,放到瀏覽器環境下,去執行而獲得最終的服務端數據,也就是jsonp是一種json數據的傳輸方式而不是格式
callback({
"message":"獲取成功",
"state":"1",
"result":{"name":"工做組1","id":1,"description":"11"}
})
閉包是指有權訪問另外一個函數做用域中的局部變量的函數. 建立閉包常見方式,就是在一個函數內部建立另外一個函數.
應用場景 設置私有變量和方法
不適合場景:返回閉包的函數是個很是大的函數
閉包的缺點就是常駐內存,會增大內存使用量,使用不當很容易形成內存泄露。
受JavaScript鏈式做用域結構的影響,父級變量中沒法訪問到子級的變量值,爲了解決這個問題,才使用閉包這個概念
像html5的新的標籤header,footer,section等就是語義化
一方面,語義化就是讓計算機可以快速的讀懂內容,高效的處理信息,能夠對搜索引擎更友好。
另外一方面,便於與他人的協做,他人經過讀代碼就能夠理解你網頁標籤的意義。
content-box 是W3C的標準盒模型 元素寬度=內容寬度+padding+border
border-box 是ie的怪異盒模型 他的元素寬度等於內容寬度, 內容寬度包括了 padding+border,只要設定了寬度高度,再設置padding 和 border 也不會撐大
好比有時候在元素基礎上添加內距padding或border會將佈局撐破 可是使用border-box就能夠輕鬆完成
Inherit:規定應從父元素繼承 box-sizing 屬性的值。
圓角邊框border-radius,添加陰影框 box-shadow / text-shadow
顏色漸變
2d 3d 轉換:transform
過分 transition
動畫 @keyframes
媒體查詢 @media 響應式優化
HTML5增長了新的內容標籤,這些標籤帶有必定的語義,使搜索引擎爬取你的網站信息更高效。
HTML4中的內容標籤級別相同,沒法區分各部份內容。而HTML5中的內容標籤互相獨立,級別不一樣,搜索引擎以及統計軟件等都可快速識別各部份內容。
最先的Cookies天然是你們都知道,問題主要就是過小,大概也就4KB的樣子,並且IE6只支持每一個域名20個cookies,太少了。
在HTML5中,本地存儲是一個window的屬性,包括localStorage和sessionStorage,從名字應該能夠很清楚的辨認兩者的區別,前者是一直存在本地的,後者只是伴隨着session,窗口一旦關閉就沒了。兩者用法徹底相同
label標籤來定義表單控制間的關係,當用戶選擇該標籤時,瀏覽器會自動將焦點轉到和標籤相關的表單控件上。
<label for="Name">Number:</label>
<input type=「text「name="Name" id="Name"/>
<label>Date:<input type="text" name="B"/></label>
是一種常見的特性,即抓取對象之後拖到另外一個位置。在 HTML5 中,拖放是標準的一部分,任何元素都可以拖放。
設置元素爲可拖放
首先,爲了使元素可拖動,把 draggable 屬性設置爲 true :
當離開的時候 ondragleave
當進入的時候ondragenter
拖動什麼 - ondragstart 和 setData()
放到何處 - ondragover :內部移動
進行放置 - ondrop
1 //建立一個FormData對象:用一些鍵值對來模擬一系列表單控件:即把form中全部表單元素的name與value組裝成一個queryString 2 3 var form = new FormData(); 4 5 //設置要傳遞的參數 6 7 form.append("doc", fileObj); 8 9 // 建立一個ajax對象 10 11 var xhr = new XMLHttpRequest(); 12 13 //規定請求的類型、URL 以及是否異步處理請求。true爲異步 14 15 //請求是異步的。由於要實時獲取到上傳的進度,則請求需是異步的,若是是同步的話,會直到請求完成才能獲取到響應 16 17 xhr.open("post", url, true); 18 19 //發送http請求:將請求發送到服務器,與後臺交互 20 21 xhr.send(form); //也能夠不攜帶參數,直接 xhr.send(); 22 23 //響應成功進入的回調函數 24 25 xhr.onreadystatechange = function(){ 26 27 //狀態4和200表明和服務器端交互成功 28 29 if(xhr.readyState==4 && xhr.status==200){ 30 31 //獲取上傳成功的返回數據 32 33 var data = xhr.responseText.trim(); 34 35 jdata = eval("("+data+")"); 36 37 } 38 39 };
//xhr.open() 與 xhr.send() 一塊兒用
//前者是規定請求的類型、url,後者是發送請求到這個url
問題一:不一樣瀏覽器的標籤默認的外補丁和內補丁不一樣
:last-child 選擇元素最後一個孩子
:first-child 選擇元素第一個孩子
:nth-child(1) 按照第幾個孩子給它設置樣式
:nth-child(even) 按照偶數
:nth-child(odd) 按照奇數
a:link {color: #FF0000} /* 未訪問的連接 */
a:visited {color: #00FF00} /* 已訪問的連接 */
a:hover {color: #FF00FF} /* 鼠標移動到連接上 */
a:active {color: #0000FF} /* 選定的連接 */
:after 選擇器在被選元素的內容後面插入內容。使用 content 屬性來指定要插入的內容。
詳情看:https://github.com/Krryxa/WORK-LEARNING/issues/9
鏈接兩個或更多的數組,並返回結果。 |
|
把數組的全部元素放入一個字符串。元素經過指定的分隔符進行分隔。 |
|
刪除並返回數組的最後一個元素(改變原數組) |
|
向數組的末尾添加一個或更多元素,並返回新的長度。(改變原數組) |
|
顛倒數組中元素的順序。(改變原數組) |
|
刪除並返回數組的第一個元素(改變原數組) |
|
從某個已有的數組返回選定的元素 |
|
對數組的元素進行排序(改變原數組) |
|
刪除元素,並向數組添加新元素。(改變原數組) |
|
返回該對象的源代碼。 |
|
把數組轉換爲字符串,並返回結果。 |
|
把數組轉換爲本地數組,並返回結果。 |
|
向數組的開頭添加一個或更多元素,並返回新的長度。(改變原數組) |
|
返回數組對象的原始值 |
第一種: new關鍵字改變this指向
1 // 構造函數版 this 2 function Fn(){ 3 this.user = "筱月"; // 此時的 this 指向 window 4 } 5 let a = new Fn(); 6 console.log(a.user); //筱月
用變量a建立了一個 Fn 的實例,此時僅僅只是建立,並無執行,而調用這個函數 Fn 的是對象 a,那麼 this 指向的天然是對象 a,那麼爲何對象 a 中會有 user,由於你已經複製了一份 Fn 函數到對象 a 中,用了 new 關鍵字就等同於複製了一份
第二種: call()
注意若是 call 和 apply 的第一個參數寫的是null,那麼 this 指向的是 window 對象
1 let a = { 2 user:"筱月", 3 fn:function(){ 4 console.log(this.user); //筱月 5 } 6 } 7 let b = a.fn; 8 // 執行 b 方法,call 的第一個參數是改變 this 指向,b 方法的 this 就是指向 call 第一個參數的對象 9 b.call(a); // 若不用call,則 b() 執行後 this 指的是 Window 對象
// call方法除了第一個參數之外還能夠添加多個參數,以下: let a = { user:"筱月", fn:function(e,ee){ console.log(this.user); // 筱月 console.log(e+ee); // 3 } } let b = a.fn; b.call(a,1,2); // 輸出 筱月 3
第三種:apply()
1 let a = { 2 user:"筱月", 3 fn:function(){ 4 console.log(this.user); //筱月 5 } 6 } 7 8 let b = a.fn; 9 b.apply(a); 10 11 // apply方法和call方法有些類似,它也能夠改變this的指向,也能夠有多個參數,可是不一樣的是,第二個參數必須是一個數組,以下: 12 13 let a = { 14 user:"筱月", 15 fn:function(e,ee){ 16 console.log(this.user); //筱月 17 console.log(e+ee); //11 18 } 19 } 20 21 let b = a.fn; 22 b.apply(a,[10,1]); 23 24 // 注意若是 call 和 apply 的第一個參數寫的是null,那麼this指向的是window對象 25 26 let a = { 27 user:"筱月", 28 fn:function(){ 29 console.log(this); // Window {...} 30 } 31 } 32 33 let b = a.fn; 34 b.apply(null);
第四種:bind()
bind方法和call、apply方法有些不一樣,以下:
bind 方法返回的是一個修改事後的函數,此時並無調用,須要將 bind 方法返回的函數執行 才能調用
1 let a = { 2 user:"筱月", 3 fn:function(){ 4 console.log(this.user); //筱月 5 } 6 7 } 8 let b = a.fn; 9 let c = b.bind(a); // 方法還沒執行,bind 方法返回的是一個修改事後的函數 10 c(); // 輸出:筱月 11 12 // 一樣bind也能夠有多個參數,而且參數能夠在 bind 返回的函數執行的時候再次添加,可是要注意的是,參數是按照形參的順序進行的 13 let aa = { 14 user:"筱月", 15 fn:function(e,d,f){ 16 console.log(this.user); //筱月 17 console.log(e,d,f); //10 1 2 18 } 19 } 20 21 let bb = aa.fn; 22 let cc = bb.bind(aa,10); // 能夠添加參數 23 cc(1,2); // 執行的時候能夠繼續添加參數
這裏就將外部的 this 放進 callback 裏面,callback 裏面就可使用外部的 this
1 //代碼一: 2 3 a(1); //執行這個會報錯 4 5 var a = function(index){ 6 7 alert(index); 8 9 } 10 11 a(2); //執行這個不會報錯
1 //代碼二: 2 3 a(1); //執行這個不會報錯 4 5 function a(index){ 6 7 alert(index); 8 9 } 10 11 a(2); //執行這個不會報錯