網路全部筆記 # 向瀏覽器的地址欄中輸入一個url按回車之後,網路中都會發生什麼? 答: 1.看瀏覽器的緩存 2.看本機的host C:/windows/system32/drivers/etc/host 127.0.0.1 localhost 3.家裡路由器,上級路由,城市的LDNS伺服器,繼續向 ...
網路全部筆記 # 向瀏覽器的地址欄中輸入一個url按回車之後,網路中都會發生什麼? 答: 1.看瀏覽器的緩存 2.看本機的host C:/windows/system32/drivers/etc/host 127.0.0.1 localhost 3.家裡路由器,上級路由,城市的LDNS伺服器,繼續向上級的DNS伺服器找,直到找到GDNS伺服器 # HTTP協議簡介 - HTTP協議分為兩個部分 1.請求 Request 請求頭: 請求方式:GET、POST... 路徑:url 協議版本:HTTP/1.1 數據體 2.響應 Response - GET請求和POST請求的區別 1.是基於什麼前提的?若什麼前提都沒有,不使用任何規範,只考慮語法和理論上的HTTP協議 GET和POST幾乎沒有任何區別,只有名字不一樣 2.若是基於RFC規範的 1).理論上(Specification):GET和POST具有相同的語法,但是有不同的語義。GET是用來獲取數據的,POST是用來發送數據的,其他方面沒有區別。 2).實現上的(Implementation):各種瀏覽器,就是這個規範的實現者。 常見的不同: a.GET的數據在URL是可見的。POST的請求不顯示在URL中 b.GET請求對長度是有限制的。POST的請求長度無限制 c.GET請求的數據可以收藏為書簽,POST請求到的數據不可收藏為書簽 d.GET請求後,按後退按鈕、刷新按鈕無影響。POST請求數據會被重新提交 e.GET編碼類型:application/x-www-form-url,POST的編碼類型有很多種: encodeapplication/x-www-form-urlencoded multipart/form-data f.GET歷史參數會被保留在瀏覽器里,POST不會保存在瀏覽器中 g.GET只允許ASCII。POST沒有編碼限制,允許發二進位 h.GET與POST相比,GET安全性較差,因為所發的數據是URL的一部分 # Cookie與Session - Cookie 1.若我們用JS的變數來存數據,那麼在頁面關閉的時候,數據就消失了 2.保持登錄狀態是怎麼做到的呢? 按照正常的HTTP協議來說,是做不到的 因為HTTP協議,上下文無關協議。 3.所以說前端頁面上,有可以持久化存儲數據的東西,一旦登陸成功,就記載在這個裡面。這就是Cookie Cookie是有限制的。 Cookie是存在瀏覽器里的,不是存在某個頁面上的。 Cookie是可以長期存儲的。 Cookie即使是保存在瀏覽器中,也是存放在不同的功能變數名稱下的。 4.登錄百度過程 1).初始狀態:沒有登陸 2).訪問百度的登錄,輸入用戶和密碼 3).若用戶名和密碼是正確的,百度的後端回想這個功能變數名稱下,設置一個Cookie。寫入用戶的基本信息(加密的) 4).以後每一次向百度發送請求,瀏覽器都會自動帶上這個Cookie 5).服務端(後端)看到了帶有ID的Cookie,就可以解析這個加密的ID,來獲取到這個用戶本身的ID 6).若能獲取到本身的ID,那麼就證明這個用戶已經登陸過了,所以後端可以繼續保留用戶的信息。 缺點:若某個壞人,複製了我瀏覽器里的Cookie,他就可以在他的電腦上登錄我的賬號了 - Session 1.Session信息是存儲在伺服器上的,Cookie信息是存儲在瀏覽器上的 數據存在Session上也有缺點: 若用戶量非常大,上億的用戶。 在用戶量很大的時候,服務端很耗資源 因為後端不止一臺伺服器,用戶的登錄信息,一般只存在一臺伺服器上。 因為用戶的登錄操作,在哪台機器上執行的,就一般存在哪台機器上。 需要通過反向代理。(輪詢,IP哈希) XSS註入攻擊,就是針對Cookie進行的攻擊。 - 發送網路請求 1.在瀏覽器中直接輸入網址(無法用代碼控制) 2.location.href="url",可以發出網路請求,但是頁面會發生跳轉(頁面會跳轉) 3.帶有src屬性的標簽,請求是可以發出的,服務端可以處理的並返回,但是返回後,能否被應用還要看瀏覽器(頁面無法處理返回結果) 4.帶有href屬性的標簽,請求是可以發出的,服務端可以處理的並返回,但是返回後,能否被應用還要看瀏覽器(頁面無法處理返回結果) 5.帶有action屬性的標簽,例如form表單,也可以向後端發出請求,但是form表單發出請求後,也會頁面跳轉(頁面會跳轉) //希望有一種方式,可以用代碼控制,頁面不會跳轉,服務端返回的結果我可以用JS繼續處理 6.ajax ```js //要素 //1.請求方式:GET、POST //2.url var xhr = null; if(window.XMLHttpRequest){ xhr = new XMLHttpRequest(); }else{//相容IE6 xhr = new ActiveXObject("Microsoft.XMLHttp"); } console.log(xhr.readyState);//0:初始化 xhr.open("get", "http://developer.duyiedu.com/edu/testAjaxCrossOrigin"); console.log(xhr.readyState);//1:與伺服器建立連接 xhr.onreadystatechange = function(){//當readyState改變,執行該函數 //readyState == 4:請求已完成,已接收到數據 //status == 200 網路請求,結果都會有一個狀態碼,來表示這個請求是否正常。200表示請求成功 //http狀態碼 //2**:表示成功 //3**:表示重定向 //4**:表示客戶端錯誤,404頁面沒找到 //5**:表示服務端錯誤 if(xhr.readyState == 4 && xhr.status == 200){ console.log(xhr.readyState);//2 3 4:請求已完成,已接收到數據 document.getElementById('test').innerText = xhr.responseText; var data = JSON.parse(xhr.responseText); console.log(data); } } xhr.send();//若open第三個參數傳true,或者不傳,為非同步模式。若傳false為同步模式 ``` - 跨域 跨域訪問資源 1.哪些東西屬於資源? JS文件算嗎?JS文件肯定是資源,但是JS文件是允許被跨域請求的 CSS文件,jpg,png等。src屬性的資源都是可以被跨域請求的。href資源大部分都是可以被跨域請求的。 2.哪些資源算是跨域請求的資源 1.後端介面的數據 2.其他域的Cookie 3.其他域的緩存 3.什麼是其他的域?怎樣算是跨域? 頁面本身:有協議(http/https),功能變數名稱,埠 要請求的數據:http://www.baidu.com:80 協議,功能變數名稱,埠號這三個,有任意一個不一樣就算跨域。 4.跨域這個行為,發生在哪裡? 答案: 1.即使跨域了(協議、功能變數名稱、埠號不一樣),請求也可以發出 2.伺服器端也是可以接收的 3.伺服器端也是可以正常處理的 4.伺服器端也是可以正常返回數據的 5.瀏覽器也能接收到這些數據 6.接收到之後,發現當前頁面的域和請求的域不同,所以判定為跨域 7.我們的代碼在這等著結果,但是因為瀏覽器判定跨域了,uhuibajieguo傳遞給我們的代碼 5.雖然跨域了,但是我們依然需要這個數據,怎麼辦? 解決跨域問題: 1.後端(別人家的)是否配合我們進行跨域 1.JSONP(正常情況下,返回的數據都是JSON格式,JSONP是一種特殊的格式 2.後端設置Access-Control-Allow-Origin屬性以支持跨域 2.後端不配合我們進行跨域 1.iframe(缺點:只能顯示,不能控制) 2.通過後端代理(自己的後端) - JSONP ```js //jsonp格式哪裡特殊? //1.發送的時候會帶上一個參數callback //2.返回的結果不是json,而是 callback名+(json數據) $.ajax({ url:'http://developer.duyiedu.com/edu/testJsonp', type:'get', dataType:'jsonp', success:function(data){ console.log(data); } }); //jsonp跨域,只能使用get方法,若我們設置的是POST方法,jQuery會自動轉為get方法。 //是不是在jsonp裡面我們只能使用get方法?是不是我們設置的POST方法都會轉為get方法? //不是,jQuery會先判斷是否同源,若同源,那麼設置的是get就是get,設置的POST就是POST;若不是同源,無論設置的是什麼,都改為get。 ``` - JSONP原理 ```js //想從一個介面獲取一個數據 //但是這個介面和當前頁面不是同源的。(也就是跨域了) //但是這個介面是支持JSONP的 //script標簽有src屬性,可以發出網路請求 //script標簽,雖然可以引用其他域的資源,瀏覽器不限制。但是瀏覽器會將返回的內容,作為JS代碼執行。 //JSONP原理: //1.判斷請求與當前頁面的域,是否同源,若同源則發送正常的ajax,就沒有跨域的事情了 //2.若不同源,生成一個script標簽。在生成一個隨機的callback名字 //3.設置script標簽的src,設置為要請求的介面 //4.將callback作為參數拼接在後面。 //-------以上是前端部分 //5.後端接受到請求後,開始準備要返回的數據 //6.後端拼接數據,將要返回的數據用callback的值和括弧包裹起來 // 例如:callback=asd123456,要返回的數據是{"a":1,"b":2}, // 就要拼接為asd12345({"a":1,"b":2}); //7.將內容返回 //--------以上是後端部分 //8.瀏覽器接收到內容,會當做js代碼執行 //9.從而執行名為asd123456()的方法,這樣我們就接收到了後端返回給我們的對象 var $ = { ajax: function(options){ var url = options.url, type = options.type, dataType = options.dataType; //判斷是否同源 //獲取目標url的域 var targetProtocol = "";//目標介面的協議 var targetHost = "";//目標介面的host,host是包含功能變數名稱和埠的 //若url不帶http,那麼訪問的一定是相對路徑,相對路徑一定是同源的。 if(url.indexOf("http://") == 0) || url.indexOf("https://") == 0){//絕對路徑 var targetUrl = new URL(url); targetProtocol = targetUrl.protocol; targetHost = targetUrl.host; }else{//相對路徑 targetProtocol = location.protocol; targetHost = location.host; } //首先判斷是否為jsonp,因為不是jsonp不用做其他的判斷,直接發送ajax if(dataType == 'jsonp'){ //要看是否同源 if(location.protocol == targetProtocol || location.host == targetHost){ //此處省略。因為同源,jsonp會當做普通的ajax請求 }else{//不同源,跨域 //隨機生成一個callback var callback = "cb" + Math.floor(Math.random() * 1000000); //給window上添加一個方法 window[callback] = options.success; //生成script標簽 var script = document.createElement("script"); if(url.indexOf("?") > 0){//表示已經有參數了 script.src = url + "&callback=" + callback; }else{//表示沒有參數 script.src = url + "?callback=" + callback; } script.id = callback; document.head.appendChild(script); } } } } $.ajax({ url:"http://developer.duyiedu.com/edu/testJsonp", type:'get', dataType:'jsonp', success:function(data){ console.log(data); } }) ``` 以上是markdown格式的筆記