URI有兩種形式,URL和URN
URL是Uniform Resource Locator的縮寫,譯爲「統一資源定位符」
URL的格式由下列三部分組成:
- 協議(或稱爲服務方式);
- 存有該資源的主機名稱(域名)或者IP地址(有時也包括端口號);
- 主機資源的具體地址,如目錄和文件名等;
URN是統一資源名稱 (Uniform Resource Name, URN)
URN它命名資源但不指定如何定位資源
URI描述了這麼一個東西:能夠用來惟一標識一個資源,URL和URN是他的兩種具體形式
因此一個URI多是一個URL,也多是一個URN,或者兩者兼具。
可是任何一個URL或者URN他們確定都是URI
好比,「阿里巴巴馬雲」當你聽到這個名字的時候,你不知道他是誰嗎?這就是惟一標識一個資源URN
可是馬雲在哪裏?電話號碼多少?你是不知道的,雖然「馬雲」兩個字能夠惟一標識他本人,可是你聯繫不上他
若是你有了他家的地址呢?XXX小區XXX號,你就能夠定位馬雲的位置了,這就是URL
無論是「阿里巴巴馬雲」仍是馬雲家的地址XXX小區XXX號,他們都是URI
HTTP協議
設計HTTP最初的目的是爲了提供
一種發佈和接收HTML頁面的方法
最先版本是1991年發佈的0.9版。該版本極其簡單,只有一個命令GET。
GET /index.html
表示,TCP 鏈接(connection)創建後,客戶端向服務器請求(request)網頁index.html。
協議規定,服務器只能迴應HTML格式的字符串,不能迴應別的格式。
HTTP協議就是瀏覽器與web服務器兩個應用之間通訊的「協議」「語言」
計算機不能像人類同樣溝通,他只是0,1的世界,想要交流就必須制定通訊的格式,而這個HTTP協議就是瀏覽器與Web服務器的溝通方式
這就是它的根本,如同你對別人豎大拇指表示稱讚,服務器看到GET方法就會返回數據,這就是瀏覽器與服務器溝通交流的方式。
換句話說,人類用語言和文字進行溝通,CS世界中的各類協議,都是計算機的溝通方式。
HTML
HTML超文本標記語言,標準通用標記語言下的一個應用
標準通用標記語言(簡稱「通用標言」),是一種定義電子文檔結構和描述其內容的國際標準語言;
早在萬維網發明以前「通用標言」就已存在,HTML也是由他發展演變而來,
能夠簡單理解爲一種藉助於標記符格式化電子文檔的語言
,平時的書寫中你能夠換行,能夠設置標題、段落,可是在電子文檔中如何表達?
計算機不能像人類同樣用眼分辨,用腦思考,想要說明這是一個標題,你必須顯式的告訴他
標記語言就是一種很是合適的解決方案
好比HTML中的"<h1>這是個標題</h1>",h1是標籤,標籤中的內容就是標題,咱們使用h1來標誌這是一個一級標題,當計算機程序解讀到<h1>時,就能夠意識到這是個標題
超級文本標記語言是萬維網(Web)編程的基礎,也就是說萬維網是創建在超文本基礎之上的。
超級文本標記語言之因此稱爲超文本標記語言,是由於文本中包含了所謂「超級連接」點
之因此沒有直接使用通用標記語言,是由於他過於複雜,HTML是簡化的變種。
須要注意,電子文檔的出現遠比web起源要早
電子文檔的最初動機就是「將書稿、文件塞到計算機中」,一份文件,有內容也有格式(文字字體,大小,間距等)
電子化的目的是經過計算機呈現,因此電子化不只僅須要記錄文件的內容,還須要記錄內容的格式(樣式),你講兩行字之間空白多一點,行間距就大一點,在計算機中如何呈現?
HTML就是標記語言的一種應用,他也只是一種電子文檔。
瀏覽器
瀏覽器就是一個應用軟件,他能夠經過HTTP協議與服務器進行交互
根本功能也很簡單,發送HTTP請求,解析顯式得到的響應數據
1991年,世界上第一個瀏覽器World Wide Web(後更名爲Nexus)由Tim Berners-Lee建立於歐洲核子物理實驗室
同時他還寫了第一個網頁服務器httpd
這個瀏覽器並不支持圖片的顯示
1993年,伊利諾伊大學厄巴納-香檳分校的NCSA組織發表NCSA Mosaic,簡稱Mosaic
是互聯網歷史上第一個獲廣泛使用和可以顯示圖片的網頁瀏覽器
並於1997年1月7日正式終止開發和支持
Mosaic發佈後,到底怎麼分辨你的瀏覽器是否支持顯示圖片呢?UserAgent就是在這樣的場景下誕生了
Mosaic將本身標誌爲NCSA_Mosaic/2.0(windows 3.1)
這也是咱們使用瀏覽器發送請求的時候請求頭有一個字段爲UserAgent的最開始緣由
著名的瀏覽器以下,國內的瀏覽器廠商都是用國外的瀏覽器內核
瀏覽器發展歷史:
1991 |
www(nexus) |
1993 |
Mosaic |
1994 |
Netscape |
1996 |
IE |
1996 |
Opera |
2003 |
safari |
2004 |
firefox |
2008 |
chrome |
有一篇頗有意思的文章, 能夠一看
http://www.cnblogs.com/ifantastic/p/3481231.html
https://webaim.org/blog/user-agent-string-history/
chrome能夠經過在瀏覽器地址欄輸入「about:version」查看UA信息
還能夠經過網站查看:http://www.useragentstring.com/
服務器
Web服務器是能夠向發出請求的瀏覽器提供文檔的程序,也是一種軟件。
遵循HTTP協議,接受瀏覽器客戶端發起的請求,並按照HTTP協議的規定響應的一種軟件。
如今也把提供web服務的專用計算機叫作web服務器,提供web服務的程序叫作web容器。
https://en.wikipedia.org/wiki/Web_server中有關於web server的介紹
還能夠經過:https://w3techs.com/technologies/overview/web_server/all 查看目前各大web Server的使用率
現代的web 容器都是強大而複雜的,可是根本是相同的,那就是接受HTTP請求,而且按照HTTP協議進行響應。
WEB周邊組件-域名與DNS
域名(Domain Name),簡稱域名、網域
是由一串用點分隔的名字組成的,表示Internet上某一臺計算機或計算機組的名稱
用於在數據傳輸時標識計算機的位置
咱們知道計算機在網絡中的通訊須要藉助於ip地址,可是ip地址即便是點分十進制,依然難以記憶
域名就是爲了簡化記憶,更加便於使用
簡言之,域名等於一個ip的名字
若是每一個ip至關於電話號碼,那麼域名就是姓名
姓名和號碼之間必然是要有映射關係
早期,網絡上計算機個數不多
將對應關係保存在一個共享的靜態文件hosts中便可,再由hosts文件來實現網絡中域名的管理
也就是說,你們經過共享這個文件來完成ip與域名的映射,這個hosts文件就是域名IP的解析器
可是隨着網絡上計算機的增多,顯然不能將全部的域名與ip地址的對應關係都記錄在文件中
因此出現了DNS(Domain Name System),爲了解決互聯網上域名與IP地址的映射解析
百度百科:「域名解析服務,最先於1983年由保羅·莫卡派喬斯發明;
原始的技術規範在882號因特網標準草案(RFC 882)中發佈。
1987年發佈的第1034和1035號草案修正了DNS技術規範,並廢除了以前的第882和883號草案。
在此以後對因特網標準草案的修改基本上沒有涉及到DNS技術規範部分的改動。」
如今的操做系統中仍舊保留hosts這一文件,只不過再也不是全網的了,已經有專門的DNS了
域名採用樹狀的層級結構,任何一個鏈接在互聯網上的主機和路由器,都有一個惟一的層次結構名字,也就是域名
這裏的域(domain)是名字空間中的一個可被管理的劃分。域還能夠劃分爲子域,而子域還能夠繼續被劃分爲子域
這就造成了子域,二級域,三級域...
每一個域名都由一個標號構成,標號之間使用小數點分割,以下圖所示
能夠認爲,將域名空間按照頂級域名進行劃分,造成了域名的基本格局,就像「四大洋,七大洲」
也能夠理解成國家行政區域的劃分。
中國
江蘇.中國
南京.江蘇.中國
因此要深刻理解域的概念,頂級域的並集就是所有的域空間
好比說,全世界共有XXX個國家和地區,那麼,就是隻有那麼多個國家和地區
任何一個域名,都是一個頂級域名的子域,頂級域的劃分,完成了域名空間的頂層管理
DNS規定,
每個標號不容許超過63個字符,也不區分大小寫
,標號中除了使用連字符外不能使用其餘的標點符號
級別最低的標號位於域名最左邊,級別最高的頂級域名位於域名最右邊
既不規定每個域名須要有多少個下級域名
也不固定每一級的域名錶明什麼意思
各級域名由他的上級域名管理機構進行管理
最高的頂級域名由ICANN進行管理
葉子節點指向物理機器
DNS解析過程
上面介紹的域名體系是邏輯上的,DNS服務器的運行按照「區」來進行劃分
域名的體系結構按照「域」來劃分,服務器實際的查詢解析,則是按照「區」,
簡言之,邏輯上就至關於按照行政區域劃分,實際管轄上則是分片區管理
區可能小於或者等於一個域,可是確定不會大於域
一個區中全部的節點必須是聯通的,每個區設置相應的
權限域名服務器(authoritative name server),
用來保存該區中全部的域名與IP地址的映射
域名服務器分類
根域名服務器
最高層次的域名服務器,最重要的域名服務器,全部的根域名服務器都知道全部的頂級域名服務器的域名和IP地址
若是全部的根域名服務器掛掉,整個互聯網將會癱瘓
頂級域名服務器
管理在該頂級域名服務器註冊的全部的二級域名,收到請求後,給出響應(要麼直接返回結果,要麼給出下一步應該查詢的域名服務器的IP地址)
權限域名服務器
負責一個區的域名服務器
若是一個權限域名服務器不能給出最後的查詢結果,會通知發出請求的DNS客戶,下一步應該找哪一個權限域名服務器
本地域名服務器
本地域名服務器不是域名管理層次中的一環,主要做用是爲了高效節能
每一個互聯網ISP ,每一個大學、機構均可以有一個本地域名服務器
windows中關於DNS的設置就是本地域名服務器,也叫作默認域名服務器
查詢方式
查詢方式共有兩種:迭代查詢,遞歸查詢
迭代查詢-->我不知道你找XXX去,一直踢皮球
遞歸查詢-->我去幫你查,一直很仗義
主機向本地域名服務器的查詢通常都是採用遞歸查詢
本地域名服務器向根域名服務器的查詢一般是採用迭代查詢
簡單理解就是域名邏輯上是樹形的層級結構,按照域進行劃分
DNS域名服務器按照區進行劃分,每一個區小於等於一個域,對域進行分片管理
DNS的域名服務器就是與域名層次等級結構相對應的一個服務器結構體系
WEB技術發展
最初,全部Web頁面都是靜態的
用戶請求一個資源,服務再返回這個資源,在瀏覽器中主要展示的是靜態的文本或圖像信息。
GIF圖片則第一次爲HTML頁面引入了動態元素
這些網站的Web頁面只是電子形式的文本,內容生成以後就是固定不變的,而後發佈到多處
在瀏覽器發展的最初階段,Web頁面的這種靜態性不成問題,科學家只是使用Internet來交換研究論文,大學院校也只是經過Internet在線發佈課程信息等
隨着網頁從學術機構走向公衆社會,網頁承載的功能便超出了學術範圍而變得越發豐富,所以早期網頁的侷限性也逐漸顯露出來
學術天然是枯燥的,走向社會就不同了,娛樂生活等等,因此用戶天然對web能提供的服務有了更多的需求(指望),這是一個很天然的需求演變
CGI
人們固然不知足於訪問web服務器上的靜態資源
1993年CGI(Common Gateway Interface)出現了
CGI定義了Web服務器與外部應用程序之間的通訊接口標準,Web服務器能夠經過CGI執行外部程序,讓外部程序根據Web請求內容生成動態的內容。
一般的處理流程是:
- 經過Internet把用戶請求送到web服務器。
- web服務器接收用戶請求並交給CGI程序處理。
- CGI程序把處理結果傳送給web服務器。
- web服務器把結果送回到用戶。
服務器在認爲這是一個CGI請求時
會調用相關CGI程序,並經過環境變量和標準輸出將數據傳送給CGI程序
CGI程序處理完數據,生成html,而後再經過標準輸出將內容返回給服務器,服務器再將內容交給用戶,CGI進程退出
在這個過程當中,服務器的標準輸出對應了CGI程序的標準輸入,CGI程序的標準輸出對應着服務器的標準輸入。
能夠理解爲,請求轉變爲了CGI程序的參數(以環境變量的形式傳遞),CGI的輸出變成了web服務器的響應(CGI程序中直接向標準輸出打印HTML頁面)
CGI是一種標準,並不限定語言。因此Java、PHP、Python均可以經過這種方式來生成動態網頁。
它規定了web服務器向CGI程序發送數據的格式約定(好比環境變量中有哪些值),以及響應的約定等內容(生成HTML頁面)。
爲何使用CGI接口,而不是直接web服務器就提供這些功能?
若是web服務器提供這些功能,必然會致使web服務器的設計與開發過於複雜
並且,一旦web服務器實現了這些功能,開發者勢必要按照web服務器提供的技術框架基礎下進行開發,大大限制了生產力
因此藉助於CGI接口,即可以提供調用外部程序處理的能力,也將這些功能從web服務器中解耦,解放了生產力。
可想而知,有了CGI,web發生了多大的變化
不只僅能夠提供靜態的資源了,還可以進行動態的處理,數據的計算等
可是,每當一個CGI請求過來時,web服務器會fork一個子進程來執行相應的CGI程序,當請求結束時,該CGI進程也隨之結束
這樣不停fork進程的開銷是很是大的,這是形成CGI程序效率低下的主要緣由
後來出現了fastcgi,是改良版的CGI
並且,試想一下,當你要用C語言或者C++等等去一點點的處理html的內容,去拼接,去打印,是否是很辛苦?
char MimeType[]="text/html"; css
fprintf(stdout, "Content-type: %s\r\n\r\n", MimeType); //輸出響應頭,響應頭以後要加兩個"\r\n" html
fprintf(stdout, "<html><head><title>這是一個CGI小程序</title></head>\n"); 前端
fprintf(stdout, "<body>這是一個由C編寫的CGI小程序</body></html>\n");
java
作過js拼接的就能夠理解,可是很顯然,以前的CGI比你作過的js的拼接還要噁心
web編程腳本語言
人們發現,對於一個HTML頁面,每每發生變化的只是不多一部分數據,很大一部分仍舊是靜態的
好比一個只有一個頁面訪問計數器的頁面,惟一動態的數據就是那個「計數」,整個的頁面的其餘部分都是靜態的。
是否是能夠將不變的部分與變化的部分進行解耦呢?
因而又進化出後來的web編程腳本語言
PHP於1994年由Rasmus Lerdorf建立,剛剛開始是Rasmus Lerdorf爲了要維護我的網頁而製做的一個簡單的用Perl語言編寫的程序。
這些工具程序用來顯示 Rasmus Lerdorf 的我的履歷,以及統計網頁流量。
後來又用C語言從新編寫,包括能夠訪問數據庫。
他將這些程序和一些表單直譯器整合起來,稱爲 PHP/FI,也就是說
最初是C語言編寫的CGI程序的封裝集成整合
PHP實現了與數據庫的交互以及用於生產動態頁面的模板引擎
PHP能夠把程序(動態內容)嵌入到HTML(模版)中去執行,不只能更好的組織Web應用的內容,並且執行效率比CGI還更高
以後96年出現的ASP和98年出現的JSP本質上也均可以當作是一種支持某種腳本語言編程(分別是VB和Java)的模版引擎
web編程腳本語言是CGI的進一步演化與抽象,使CGI的開發使用更加高效易用,核心思想仍是CGI
有了這些腳本語言,搭配上後端的數據庫技術,Web的功能更增強勁,能夠經過Web技術來構建幾乎全部的應用系統。
企業開發平臺
兩大重要陣營J2EE/.NET
Sun公司在1998年發表JDK1.2版本的時候, 使用了新名稱Java 2 Platform,即「Java2平臺」
修改後的JDK稱爲Java 2 Platform Software Develping Kit,即J2SDK。
並分爲標準版(Standard Edition,J2SE), 企業版(Enterprise Edition,J2EE),微型版(MicroEdition,J2ME)。J2EE便由此誕生。
當Web開始普遍用於構建大型應用時,系統的穩定性安全性分佈式等方面的要求變得更高
在許多企業級應用中,例如數據庫鏈接、郵件服務、事務處理等都是一些通用企業需求模塊
這些模塊若是每次在開發中都由開發人員來完成的話,將會形成開發週期長和代碼可靠性差等問題
因而許多大公司開發了本身的通用模塊服務,這些服務性的軟件系列統稱爲中間件
J2EE就是使用Java語言,開發企業級web應用的一整套的解決方案
Java Servlet、Java Server Pages (JSP)和Enterprise Java Bean (EJB )是Java EE中的核心規範
Servlet和JSP是運行在服務器端的Web組件
讓Java開發者同時擁有了相似CGI程序的集中處理功能和相似PHP的HTML嵌入功能
此外,Java的運行時編譯技術也大大提升了Servlet和JSP的執行效率
Sun正式發佈了J2EE版本後,緊接着,遵循J2EE標準,爲企業級應用提供支撐平臺的各種應用服務軟件爭先恐後地涌現了出來。
IBM的WebSphere、BEA的WebLogic都是這一領域裏最爲成功的商業軟件平臺。
簡言之,Java自己的跨平臺性很是適合web應用開發,Java也抓住了這一機遇,提供了企業級應用一整套的開發方案。
框架的百家爭鳴時代
隨者兩大平臺的誕生,web的技術發展趨於成熟與穩定,人們但願可以更好更快更高效的開發web
各類輔助web開發的技術,百花齊放,百家爭鳴
web應用愈來愈複雜,各類功能的頁面,各類各樣的URL地址,大量的後臺數據
MVC的概念被引入到web項目中來,出現了Structs Spring MVC等
控制器Controller負責響應請求,協調Model和View
Model,View和Controller的分開,是一種典型的關注點分離的思想,
不只使得代碼複用性和組織性更好,使得Web應用的配置性和靈活性更好。
此時,數據的訪問也不只僅是直接sql訪問,出現了ORM(Object Relation Mapping)的概念
2001年出現的Hibernate就是其中的佼佼者
更多的全棧框架開始出現,好比2003年出現的Java開發框架Spring
同時更多的動態語言也被加入到Web編程語言的陣營中
2004年出現的Ruby開發框架Rails,2005出現的Python開發框架Django
都提供了全棧開發框架,或者自身提供Web開發的各類組件,或者能夠方便的集成各類組件。
前端技術發展
JavaScript
隨着web服務器的發展,在可以進行動態數據的處理以後,涌現出來了新的問題。
服務器負責表單的一些校驗工做
看起來好像沒什麼,可是站在當時的環境下,在那個絕大多數用戶都在使用調制解調器上網的時代,網絡是很低速的
用戶填寫完一個表單點擊提交,須要不少秒,才能獲得服務器的反饋
然而最後完了服務器反饋給你說某個地方填錯了......你是否是會崩潰?
人們但願是否能夠在客戶端進行這些基礎校驗工做,這就是Js誕生的背景
JavaScript誕生於1995年,前身是livescript
最開始是由瀏覽器廠商Netscape(網景)着手開發的,起初這是一種「自導自演」的語言。
你能夠這麼理解,瀏覽器是我本身開發的一個軟件,我爲了實現某種功能定義了一些規範條件語法,創造了一種語言
好比我說在我這個軟件內var能夠定義一個變量,個人這個軟件就認識這個var,別人家的瀏覽器實際上是不認識的
我本身的軟件,能夠解釋我自定義的語言
就比如你定義了一個XML文件的格式,而後你編寫相應的方法用於解析XML,是相似的邏輯
固然,瀏覽器不止一家,出現了這麼一個好東西,你們就會都去搞,撕逼大戰熱火朝天
最終出來機構調節停火,也就是出臺了
ECMAScript,
這是一個
規範
由ECMA-262定義的ECMAScript其實與Web瀏覽器沒有依賴關係,Web瀏覽器只是ECMAScript實現可能的宿主環境之一
JavaScript是一個ECMAScript規範的實現,就好像HotSpot遵循java虛擬機規範同樣
完整的js實現包括
1.核心(ECMAScript)
2.文檔對象模型(DOM)
3.瀏覽器對象模型(BOM)
CSS
另外因爲項目應用規模的不斷擴大,頁面也愈來愈越複雜,你會發現,將樣式與模板放到一個頁面上
是一個很是糟糕的設計思路
1996年12月W3C推出了CSS規範的第一個版本
CSS(Cascading Style Sheets,層疊樣式表)是一種將表示樣式應用到標記的系統
CSS以設計、改變其HTML頁面的樣式而知名,並使用於Web和其餘媒介,如XML文檔中
CSS依附於HTML的結構對其樣式進行渲染
AJAX/前端框架/Node
而對於瀏覽器端,除了前面提到的js css
在98年還出現了AJAX,05年以後大放異彩
一個頁面上,有絕大多數的數據是固定不變的,因此演變出模板的形式,動態的渲染數據
然而,在不少時候,也並非頁面上的數據所有都須要變化,可能須要變化的僅僅只有很細微的一個地方
可是,哪怕你僅僅須要變更的是一個數字而已,也仍舊須要從新載入整個頁面,這顯然是資源的浪費,以及不必的等待
ajax就是爲了解決這個問題的而出現的一種局部刷新的技術
AJAX即「Asynchronous JavaScript and XML」(異步的JavaScript與XML技術)
指的是一套綜合了多項技術的瀏覽器端網頁開發技術
能夠基於JavaScript的XmlHttpRequest的用於建立交互性更強的Web應用。
ajax的出現,可讓先後端工程師以ajax接口爲分界點進行先後端分離
規定好交互接口後,先後端工程師就能夠根據約定,分頭開工
開發環境中經過Mock等方式進行測試,同時在特定時間節點進行先後端集成測試。
可是,隨着業務功能的愈發複雜
這種模式本質上和JSP時代的Web開發並沒有本質區別,只不過是將複雜的業務邏輯從JSP文件轉移到了JavaScript文件中而已。
因此很天然的又把MVC模式應用到了前端
前端開發也出現了大量的MVC框架
比較典型的包括BackboneJS, AngularJS, EmberJS, KnockoutJS。
隨着各大瀏覽器的競爭,引擎愈來愈牛逼
Google V8引擎的性能已經足以運行大型Javascript程序
在V8之上加以網絡、文件系統等內置模塊,造成了現在的Node.js
隨着Node.js的出現,JavaScript開始擁有在服務端運行的能力
它的異步本質使得Node.js在處理I/O密集型業務中優點凸顯
而大多Web業務中I/O性能都是瓶頸
關於網絡的演變,能夠查看 http://www.evolutionoftheweb.com/ 圖形化的展現了演進過程。
總結
以上能夠看得出來,WEB的發展從提出一直都是在迅猛發展,WEB架構的核心思想一直都沒有變化過:BS結構瀏覽器和服務器,經過HTTP協議交互,藉助於URL進行資源定位,最終獲取響應,而響應的內容則是HTML。
儘管WEB的規模在不斷的變化,甚至能夠說與日俱增的變化,核心是沒有變化的
而WEB變化的方向也能夠說是很是明確的,那就是工做的精細化拆分,不斷地分工,不斷地分工。
最開始須要動態處理的能力,因此藉助於CGI程序,將處理能力外包;
項目不斷擴大,因此按照功能進行拆分引入MVC模式;
引入模式後爲了更便於開發維護,又出現了各類框架簡化開發;
靜態的模板內容和動態的數據內容相互耦合,因此進行分離;
模板與樣式相互偶爾交織在一塊兒,因此HTML結構與樣式分離;
動態能力所有位於服務器因此出現了JS使客戶端具備處理能力;
同步的處理數據量太大卻有時又沒有必要,因此出現了AJAX;
請求太多,一臺服務器沒法處理,因此出現了負載均衡;
一個數據庫數據量太大,因此開始分庫分表;
應用體量太大,因此將應用服務自己進行拆分,出現了分佈式;
等等................................
能夠看得出來,整個WEB項目發展基調如此:
活範圍太寬,事兒太多怎麼辦?拆分、解耦!!!
活仍是太多了幹不完,咋整?分工!!!
分工、解耦、拆分、分工、解耦,拆分、水平拆分、垂直拆分、各類拆分.........