前端websocket框架,AJAX--URL--http、https、websocket協議、跨域

 2023-10-05 阅读 23 评论 0

摘要:AJAXAJAX -- URL -- http、https、websocket協議 -- 跨域一. 客戶端與服務器二. url地址2.1 概念:URL(全稱是UniformResourceLocator)中文叫統一資源定位符,用于標識互聯網上每個資源的唯一存放位置。瀏覽器只有通過URL地址,才能正確定位

AJAX

AJAX – URL – http、https、websocket協議 – 跨域

一. 客戶端與服務器

前端websocket框架。請添加圖片描述

  • 上網過程中,負責獲取和消費資源的電腦,叫做客戶端。
  • 上網過程中,負責存放和對外提供資源的電腦,叫做服務器。

二. url地址

2.1 概念:URL(全稱是UniformResourceLocator)中文叫統一資源定位符,用于標識互聯網上每個資源的唯一存放位置。瀏覽器只有通過URL地址,才能正確定位資源的存放位置,從而成功訪問到對應的資源。

常見的URL舉例:
http://www.baidu.com
http://www.taobao.com
http://www.cnblogs.com/liulongbinblogs/p/11649393.html

2.2 url地址的組成部分

URL地址一般由三部組成:
① 客戶端與服務器之間的通信協議
② 存有該資源的服務器名稱
③ 資源在服務器上具體的存放位置

跨域是設置前端還是設置后端。請添加圖片描述

2.3 網頁的打開過程 ***

請添加圖片描述

注意:

post跨域,客戶端與服務器之間的通信過程,分為 請求 – 處理 – 響應 三個步驟。
網頁中的每一個資源,都是通過 請求 – 處理 – 響應 的方式從服務器獲取回來的。

面試題:從輸入URL到頁面展示,這中間發生了什么

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-UiNaRme9-1631186210983)(.\images\dns.png)]

  1. 用戶輸入關鍵詞,地址欄判斷是搜索內容還是url地址。
    如果是搜索內容,會使用瀏覽器默認搜索引擎加上搜索內容合成url;
    如果是域名會加上協議(如https)合成完整的url。
  2. 然后按下回車。瀏覽器進程通過IPC(進程間通信)把url傳給網絡進程(網絡進程接收到url才發起真正的網絡請求)。
  3. 網絡進程接收到url后,先查找有沒有緩存。(強制緩存和協商緩存 https://www.cnblogs.com/tugenhua0707/p/10807289.html)
    有緩存,直接返回緩存的資源。
    沒有緩存。(進入真正的網絡請求)。首先獲取域名的IP,系統會首先自動從hosts文件中尋找域名對應的 IP 地址,一旦找到,和服務器建立TCP連接;如果沒有找到,則系統會將網址提交 DNS 域名解析服務器進行 IP 地址的解析。
  4. 利用IP地址和服務器建立TCP連接(3次握手4次揮手了解)。
  5. 建立連接后,瀏覽器構建數據包(包含請求行,請求頭,請求正文,并把該域名相關Cookie等數據附加到請求頭),然后向服務器發送請求消息。
  6. 服務器接收到消息后根據請求信息構建響應數據(包括響應行,響應頭,響應正文),然后發送回網絡進程。
  7. 網絡進程接收到響應數據后進行解析。
    如果發現響應行的返回的狀態碼為301,302,說明服務器要我們去找別人要數據,找誰呢?找響應頭中的Location字段要,Location的內容是需要重定向的地址url。獲取到這個url一切重新來過。
    如果返回的狀態碼為200,說明服務器返回了數據。
  8. 好了,獲取到數據以什么方式打開呢?打開的方式不對的話也不行。打開的方式就是 Content-Type。這個屬性告訴瀏覽器服務器返回的數據是什么類型的。如果返回的是網頁類型則為 text/html,如果是下載文件類型則為 application/octet-stream 等等。打開的方式不對,則得到的結果也不對。
    如果是下載類型,則該請求會被提交給瀏覽器的下載管理器,同時該請求的流程到此結束。
    如果是網頁類型,那么瀏覽器就要準備渲染頁面了。
  9. 渲染頁面開始。瀏覽器進程發出“提交文檔”(文檔是響應體數據)消息給渲染進程,渲染進程接收到消息后會和網絡進程建立傳輸數據的通道,網絡進程將“文檔”傳輸給渲染進程。
  10. 一旦開始傳輸,渲染進程便開始渲染界面

socketjs?渲染流程: 特別耗性能 。框架 使用 虛擬dom

構建 DOM 樹
輸入:HTML 文檔;
處理:HTML 解析器解析;
輸出:DOM 數據解構。
樣式計算
輸入:CSS 文本;
處理:屬性值標準化,每個節點具體樣式(繼承、層疊);
輸出:styleSheets(CSSOM)。
布局(DOM 樹中元素的計劃位置)
DOM & CSSOM 合并成渲染樹;
布局樹(DOM 樹中的可見元素);
布局計算。
分層
特定節點生成專用圖層,生成一棵圖層樹(層疊上下文、Clip,類似 PhotoShop 里的圖層);
擁有層疊上下文屬性(明確定位屬性、透明屬性、CSS 濾鏡、z-index 等)的元素會創建單獨圖層;
沒有圖層的 DOM 節點屬于父節點圖層;
需要剪裁的地方也會創建圖層。
繪制指令
輸入:圖層樹;
渲染引擎對圖層樹中每個圖層進行繪制;
拆分成繪制指令,生成繪制列表,提交到合成線程;
輸出:繪制列表。
分塊
合成線程會將較大、較長的圖層(一屏顯示不完,大部分不在視口內)劃分為圖塊(tile, 256256, 512512)。
光柵化(柵格化)
在光柵化線程池中,將視口附近的圖塊優先生成位圖(柵格化執行該操作);
快速柵格化:GPU 加速,生成位圖(GPU 進程)。
合成繪制
繪制圖塊命令——DrawQuad,提交給瀏覽器進程;
瀏覽器進程的 viz 組件,根據DrawQuad命令,繪制在屏幕上。

  1. 傳輸完畢,渲染進程會發出“確認提交”消息給瀏覽器進程。

  2. js跨域請求的三種方法、瀏覽器在接收到“確認提交”消息后,更新瀏覽器界面狀態(包括地址欄信息,仟前進后退歷史,web頁面和網站安全狀態)。

  3. 頁面此時可能還沒有渲染完畢,而一旦渲染完畢,渲染進程會發送一個消息給瀏覽器進程,瀏覽器接收到這個消息后會停止標簽圖標的加載動畫。

自此,一個完整的頁面形成了。

2.4 網頁中如何請求數據

websocket跨域推送數據。如果要在網頁中請求服務器上的數據資源,則需要用到 XMLHttpRequest 對象。
XMLHttpRequest(簡稱 xhr)是瀏覽器提供的 js 成員,通過它,可以請求服務器上的數據資源。
最簡單的用法 var xhrObj = new XMLHttpRequest()

三. ajax

Ajax 的全稱是 Asynchronous Javascript And XML(異步 JavaScript 和 XML)。
通俗的理解:Ajax使用XMLHttpRequest對象與服務器端腳本進行通信,支持“異步”通信

  • 節省用戶操作時間,提高用戶體驗,減少數據請求
  • 傳輸獲取數據
  • AJAX = 異步 JavaScript和XML(標準通用標記語言的子集)。
  • AJAX 是一種用于創建快速動態網頁的技術。
  • 通過在后臺與服務器進行少量數據交換,AJAX 可以使網頁實現異步更新。這意味著可以在不重新加載整個網頁的情況下,對網頁的某部分進行局部更新

3.1 ajax優點

  • 減少數據傳輸
  • 減輕Web 服務器負荷
  • 頁面無刷新,提供更好客戶體驗度的程序

3.2 ajax缺點

  • 存書簽問題(解決)
    由于執行動作URL不跳轉,所以無法存書簽,無法收藏分享鏈接(可以通過瀏覽器hash、history來判斷和加載不同動作)
  • 瀏覽器前進后退問題(解決)
    瀏覽器中的操作無法正常前進后退按鈕(HTML5后,可以通過window.history.state實現)
  • SEO問題
    搜索引擎無法抓取和收錄Ajax內部請求的內容,不利于seo收錄網站 ,vue ssr 服務器端渲染(解決的)
  • 網絡延遲問題
    使用一個可視化的組件來告訴用戶系統正在進行后臺操作并且正在讀取數據和內容
  • 流媒體內容支持有限(不存在)
    XMLHttpRequest2提供了更好支持
  • 設備支持問題(不存在)
    一些舊的手持設備(如手機、PDA等)對JS和Ajax支持有限

3.3 ajax流程***

面試題: 背下來 ***

js跨域請求。1.打開瀏覽器,發送請求

2.向地址欄輸入地址

3.回車提交

4.等待服務器返回數據,并且接收

5.渲染到頁面上

需要使用的知識點:

  • Open方法 打開某個鏈接 需定義三個參數

  • xhr.open("GET","test1.txt",true);
    
  • 三個參數的含義
    1、提交方式 Form-method
    2、提交地址 Form-action
    3、異步(同步)默認為true 表示是異步請求

  • Send方法
    發送數據請求,相當于Form的submit

  • 請求狀態監控
    onreadystatechange事件
    readyState屬性:請求狀態
    0 (未初始化)還沒有調用open()方法
    1 (載入)已調用send()方法,正在發送請求
    2 (載入完成)send()方法完成,已收到全部響應內容
    3 (解析)正在解析響應內容
    4 (完成)響應內容解析完成,可以在客戶端調用了
    status屬性:服務器(請求資源)的狀態
    返回的內容
    responseText:返回以文本形式存放的內容
    responseXML:返回XML形式的內容

完整流程

<button id="btn">點擊獲取數據</button><div id="con"></div><script>window.onload = function () {//獲取dom節點var oBtn = document.getElementById("btn");var oCon = document.getElementById("con");//綁定事件oBtn.onclick = function () {// 1.使用 XMLHttpRequest 創建 ajax對象//創建 ajax對象var xhr = new XMLHttpRequest();// 2.向地址欄輸入地址  使用 open函數設置請求方式,請求地址,是否異步//打開瀏覽器,設置 請求方式,請求地址,是否異步xhr.open("get", "./user.json", true);// 3.回車提交 使用 send發送請求xhr.send();// 4.綁定 onreadystatechange 事件 ,等待服務器返回數據, 并且接收//綁定 onreadystatechange 事件  ,當 url請求的狀態值發生變化時會觸發這個事件xhr.onreadystatechange = function () {if (xhr.readyState == 4) {//數據已經從 服務器端返回了//接收數據var data = xhr.responseText;//console.log( data);// 5.需要將 字符串轉json對象,渲染到頁面上//需要將 字符串轉json對象var datajson = JSON.parse(data);console.log(datajson);oCon.innerHTML = `<span>名字:${datajson.name}</span><span>年齡:${datajson.age}</span>`;}}}}</script>

拋出異常處理:

 var aa = 12;
//代碼不想報錯,然后又想知道有沒有錯誤,錯誤是什么,就可以使用 捕獲異常
try {alert(a);
} catch (e) {//捕獲異常console.log(e);
}

ajax ie瀏覽器兼容性處理,使用拋出異常

try {var xhr = new XMLHttpRequest();
} catch (e) {var xhr = ActiveXObject("Microsoft.XMLHTTP");//ie低版本
}

3.4 ajax提交數據到php服務器端

3.4.1 準備工作

a.安裝 phpstudy

b.打開面板后,左側選擇網站,打開面板后左上角有個創建網站按鈕,點擊后創建新站點,

c.將準備好的php文件拷貝進去

d.啟動 Apache服務器

3.4.2 get方式提交

<button id="btn">點擊獲取數據</button>
<div id="con"></div>
<script>window.onload = function () {var oBtn = document.getElementById("btn");var oCon = document.getElementById("con");oBtn.onclick = function () {var xhr = new XMLHttpRequest();//get傳參xhr.open("get", "./get.php?user=lili&pwd=123456", true);xhr.send();xhr.onreadystatechange = function () {if (xhr.readyState == 4) {//數據已經從 服務器端返回了var data = xhr.responseText;console.log(data);oCon.innerHTML = `<span>${data}</span>`;}}}}//注意:本實例,需要使用 php 的服務器才能解析 get.php的文件//打開小皮,啟動 Apache//在瀏覽器輸入:http://127.0.0.1/04-ajax-get.html

get方式的數據提交服務器一般跟在url的后面,get方式提交的數據有大小限制

-  **Firefox** 3.0.3: 當$len 賦值為4053時出錯,可見最長字長4098
-  IE7.0: 2083, 結果與官方說法一致
-  Opera 9.60: 4098 , **Firefox**3.0.3 相同
-   google chrome 0.2.149.30: 4098, 與**Firefox**3.0.3,Opera 9.60相同
xhr.open('get','get.php?user=qqq&pwd=123456',true);

3.4.3 post方式提交

優點:1.使用 頭部將post數據提交到 服務端,不會顯示在 地址欄,更安全;2.post方式傳輸的數據量不限制

? post 數據加密了么? 沒加密

? 加密:1.使用 MD5、sha1 、對稱加密、非對稱加密 (手動寫)

? 2.https協議

xhr.open('post','post.php',true);
xhr.setRequestHeader('content-type','application/x-www-form-urlencoded');
//3.回車提交
xhr.send('user=lili&pwd=123456');

3.5 ajax封裝 了解內容

各位同學,發現了沒有,ajax的好多代碼都是固定格式的,所以,我們需要把他封裝一下,以方便我們后期調用。

//參數:

method 請求方式

url 請求地址

success 回調函數

data 帶給 服務端的數據

type 同步還是異步

ajax.js

//參數:
// method  請求方式  string
// url     請求地址  string
// success 回調函數  function
// data    帶給 服務端的數據  string
// type    同步還是異步    boolean
function ajax(method, url, data, success, type) {//1.創建 xml 對象try {var xhr = new XMLHttpRequest();} catch (e) {var xhr = ActiveXObject("Microsoft.XMLHTTP");}xhr.open(method, url, type);//判斷請求方式if (method == "get") {xhr.send();} else {xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded");xhr.send(data);}//綁定事件xhr.onreadystatechange = function () {//判斷 數據是不是正常傳回來了if (xhr.readyState == 4) {//保險  status == 200 服務器端正常返回if (xhr.status == 200) {success && success(xhr.responseText);} else {alert("訪問出錯");}}}
}

調用:

<button id="btn">點擊獲取數據</button><div id="con"></div><script src="./ajax.js"></script><script>window.onload = function () {var oBtn = document.getElementById("btn");var oCon = document.getElementById("con");oBtn.onclick = function () {//function ajax(method, url, data, success, type) ajax("get", "./getNews.php", "", function (data) {console.log(data);var datajson = JSON.parse(data);str = "";datajson.forEach((item, index) => {str += `<p >${item.title} - ${item.date}</p>`;})oCon.innerHTML = str;}, true);}}</script>

四.表單提交數據

4.1 什么是表單

表單 即form,可以向服務器提交數據,比如:提交用戶信息

  • action 提交到哪里
  • method 提交方式

4.2 Get和Post的區別

  • 傳輸方式的區別
    Get通過url地址傳輸
    Post通過瀏覽器內部傳輸
  • 傳輸數據量
    Get有數據量限制,每個瀏覽器都不同
    Post理論上無限

實例:

get:

<form action="get.php" method="get"><!-- 表單提交時,表單項一定要寫name get方式 數據是在url后面傳輸到服務端的,大小有限制,不安全--><input type="text" name="user" id="" /><input type="password" name="pwd" id="" /><button type="submit">提交表單</button></form>

post:

<form action="post.php" method="post"><!-- 表單提交時,表單項一定要寫name post方式 數據是在傳輸包的頭部傳輸到服務端的 ,大小無限制,和get相比更安全--><input type="text" name="user" id="" /><input type="password" name="pwd" id="" /><button type="submit">提交表單</button></form>

五.jquery ajax

瀏覽器中提供的 XMLHttpRequest 用法比較復雜,所以 jQuery 對 XMLHttpRequest 進行了封裝,提供了一系列 Ajax 相關的函數,極大地降低了 Ajax 的使用難度。
jQuery 中發起 Ajax 請求最常用的三個方法如下:

  • $.get()
  • $.post()
  • $.getJSON()
  • $.ajax()

5.1 $.get()函數的語法

jQuery 中 $.get() 函數的功能單一,專門用來發起 get 請求,從而將服務器上的資源請求到客戶端來進行使用。
$.get() 函數的語法如下:

$.get(url,[data],[callback])

參數:

  • url 要請求的資源地址
  • data 請求資源期間要攜帶的參數
  • callback 請求成功是的回調函數
//get方式獲取
$.get('film.json',function(data){console.log(data);
})

5.2 $.post()函數的語法

 $(function () {$.ajax({type: "post",url: "http://www.51houniao.com/requirement/request/getMatchedProducts",data: JSON.stringify({desc: false,orderBy: "outtime",product_type: 2,pageSize: 100}),//候鳥的后臺不支持 對象形式的參數contentType: "application/json;charset=UTF-8",//設置頭部success: function (data) {console.log(data);}})})

5.3 $.getJSON()函數寫法

//getJSON  專門獲取json數據的
$.getJSON('film.json',function(data){console.log(data);
});

5.4 $.ajax() 函數

相比于 $.get() 和 $.post() 函數,jQuery 中提供的 $.ajax() 函數

$.ajax({type:"get",//獲取數據的方式  get  post   url:"film.json",//url地址  如果訪問的是php,那么請打開php的服務器   必選async:true,//異步data:"",//獲取數據時的傳參dataType:"json",//返回值類型   jsonp 支持跨域 success:function(data){//成功的回調函數  必選console.log(data);//jquery返回的數據不需要解析var data = data.data.films;for(var i = 0;i<data.length;i++){var $li = $('<li>'+data[i].name+'</li>');$('#con').append($li);}},error:function(e){console.log(e);}
})

六.跨域***

6.0 為什么會出現跨域問題

因為 ,瀏覽器同源策略,增加安全性,同源策略又叫同域(域名)策略
只有同一個域名下的數據可以相互訪問,不同域名下進行相互之間訪問時就會被組織,提示你蛞蝓了,子域名不一樣與會存在跨域問題

1.在同一個公司 ,163 ,做不同業務的需要的子域名不一樣,解決跨域問題

2.爬取其他網站的數據, 需要解決跨域問題

注意:微信 用戶不需要考慮跨域問題,ios、安卓沒有跨域問題

	出于瀏覽器的同源策略限制。**同源策略**(Sameoriginpolicy)是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,則瀏覽器的正常功能可能都會受到影響。可以說Web是構建在同源策略基礎之上的,瀏覽器只是針對同源策略的一種實現。同源策略會阻止一個域的javascript腳本和另外一個域的內容進行交互。所謂同源(即指在同一個域)就是兩個頁面具有相同的協議(protocol),主機(host)和端口號(port)

當一個請求url的協議、域名、端口三者之間任意一個與當前頁面url不同即為跨域

請添加圖片描述

跨域限制

【1】無法讀取非同源網頁的 Cookie、LocalStorage 和 IndexedDB

【2】無法接觸非同源網頁的 DOM

【3】無法向非同源地址發送 AJAX 請求 ***

跨域實例:

演示跨域
<script src="./js/jquery.min.js"></script>
<script>$(function () {$.get("http://127.0.0.1/getNews.php", "", function (data) {console.log(data);});})//實例,需要在 vscode中點擊右鍵菜單打開//打開的地址:http://127.0.0.1:5501/01-ajax-kuayu.html//http://127.0.0.1:5501 請求 http://127.0.0.1/getNews.php ,所以產生了跨域/*報錯:Access to XMLHttpRequest at 'http://127.0.0.1/getNews.php' from origin 'http://127.0.0.1:5501' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.*/
</script>

2.運行程序,會看到跨域
3.在瀏覽器-開發者工具中會看到

已攔截跨源請求:同源策略禁止讀取位于 http://127.0.0.1:8888/getNews.php 的遠程資源。(原因:CORS 頭缺少 'Access-Control-Allow-Origin')。

說明跨域了

解決跨域的常用方式有以下幾種:

6.1 后臺設置允許跨域請求 CORS header(‘Access-Control-Allow-Origin: *’);

這種前端工程師了解即可

6.2原生js解決跨域 **

1.原生解決跨域問題的原理

js跨域的原理<script>function success(data) {console.log("拿到數據了");console.log(data);}</script><script>success({ name: "lili", age: 18 })</script>

getdata.js

success({ name: "lili", age: 18 })

html

<!-- script 標簽的 src屬性 天生具備跨域能力 --><script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script><script>function success(data) {console.log("拿到數據了");console.log(data);}</script><script src="./js/getdata.js?callback=success"></script><!-- callback=success 就相當于  success({ name: "lili", age: 18 }) -->

原生js解決跨域問題

/*1. script標簽的src屬性 天生就具備 跨域能力2.js原生跨域必須后臺代碼支持*/window.onload = function () {//創建 script標簽var oScript = document.createElement("script");oScript.src = "http://127.0.0.1/getNewsjs.php?callback=success";var oHeader = document.getElementsByTagName('head')[0];oHeader.appendChild(oScript);}function success(data) {console.log(data);}

百度搜索的實例

<input type="text" name="word" id="word" placeholder="請輸入想要搜索的內容" /><button id="btn">搜索</button><div id="con"></div><script>var oCon = document.getElementById("con");//https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=js&cb=JSON_yy//需求:輸入關鍵字,點擊 按鈕搜索內容window.onload = function () {//1.獲取domvar oBtn = document.getElementById("btn");var oWord = document.getElementById("word");//2.綁定事件oBtn.onclick = function () {//3.獲取文本框內容var txt = oWord.value;//4.跨域獲取 百度搜索的數據//4.1 創建 標簽var oScript = document.createElement("script");oScript.src = "https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=" + txt + "&cb=success";//cb 因為 咱百度的后臺工程師定義的接收變量的可以是 cbvar oHead = document.getElementsByTagName("head")[0];oHead.appendChild(oScript);}}function success(data) {console.log(data);var str = "";data.s.forEach(item => {str += `<p>${item}</p>`;})oCon.innerHTML = str;}</script>

6.3 jquery jsonp解決跨域

	<script src="./js/jquery.min.js"></script><script>$(function () {$.ajax({type: "get",url: "http://127.0.0.1/getNewsjs.php",data: "",async: true,dataType: "jsonp",//表示支持跨域 ,success: function (data) {console.log(data);},error: function (err) {console.log(err);}})})//jquery 跨域的原理:和js的跨域的原理一樣,只不過,咱jquery工程師,將 js的跨域封裝到了  dataType: "jsonp"</script>

6.4 在前端還可以在打包前使用proxy配置解決跨域,很常用 ***

6.5 后臺配置 nginx 反向代理服務器 解決跨域 ***

6.6 ajax 配合 promise使用 ***

手寫promise

      var pro = new Promise(function(resolve, reject){setTimeout(function(){//resolve('success');reject('fail');}, 2000);});pro.then(function(res){//接收成功的數據console.log(res);}, function(err){//接收失敗的數據console.log(err);})

ajax在使用的時候,如果是多個數據請求,容易產生地獄回調問題,可以使用 promise解決

例如:

$(function () {$.getJSON('./json/01.json', function (data) {console.log(data);var list = data.matchedProducts;for (var i = 0; i < list.length; i++) {var $li = $(`<li>${list[i].collection_num} - ${list[i].pro_title}</li>`);$('#list').append($li);}//調用 第二頁數據$.getJSON('./json/02.json', function (data) {console.log(data);var list = data.matchedProducts;for (var i = 0; i < list.length; i++) {var $li = $(`<li>${list[i].collection_num} - ${list[i].pro_title}</li>`);$('#list').append($li);}//調用 第三頁數據$.getJSON('./json/03.json', function (data) {console.log(data);var list = data.matchedProducts;for (var i = 0; i < list.length; i++) {var $li = $(`<li>${list[i].collection_num} - ${list[i].pro_title}</li>`);$('#list').append($li);}})})})})

以上實例,可以使用promise解決

$(function () {function getJson(page) {//創建peomise對象var p = new Promise(function (resolve, reject) {//獲取數據$.getJSON("./json/0" + page + ".json", function (data) {//將獲取到的后臺數據使用 resolve帶回resolve(data);})});return p;}//渲染頁面的函數function writeHTML(data) {var list = data.matchedProducts;for (var i = 0; i < list.length; i++) {var $li = $(`<li>${list[i].collection_num} - ${list[i].pro_title}</li>`);$('#list').append($li);}}//調用 promisegetJson(1).then(function (data) {console.log(data);// 渲染頁面writeHTML(data);//獲取第二頁數據return getJson(2)}).then(function (data) {// 渲染頁面writeHTML(data);//獲取第二頁數據return getJson(3)}).then(function (data) {// 渲染頁面writeHTML(data);}).catch(function (err) {console.log(err);})})

promise.all的使用

$(function () {const p1 = new Promise(function (resolve, reject) {$.getJSON("./json/01.json", function (data) {resolve(data);})})const p2 = new Promise(function (resolve, reject) {$.getJSON("./json/02.json", function (data) {resolve(data);})})const p3 = new Promise(function (resolve, reject) {$.getJSON("./json/03.json", function (data) {resolve(data);})})//渲染頁面的函數function writeHTML(list) {for (var i = 0; i < list.length; i++) {var $li = $(`<li>${list[i].collection_num} - ${list[i].pro_title}</li>`);$('#list').append($li);}}//調用 Promise.all//如果數據組中的promise有一個返回是錯誤的,那么promise不會繼續進行Promise.all([p1, p2, p3]).then((res) => {//console.log(res);//重組數據var mydata = [];res.forEach((item, index) => {mydata = mydata.concat(item.matchedProducts);})console.log(mydata);writeHTML(mydata)})})
Promise.race的使用

顧名思義,Promse.race就是賽跑的意思,意思就是說,Promise.race([p1, p2, p3])里面哪個結果獲得的快,就返回那個結果,不管結果本身是成功狀態還是失敗狀態。

Promise.allSettled 的使用

在多個promise同時進行時咱們很快會想到使用Promise.all來進行包裝, 但是由于Promise.all的短路特性, 三個提交中若前面任意一個提交失敗, 則后面的表單也不會進行提交了, 這就與咱們需求不符合.

Promise.allSettledPromise.all類似, 其參數接受一個Promise的數組, 返回一個新的Promise, 唯一的不同在于, 其不會進行短路, 也就是說當Promise全部處理完成后我們可以拿到每個Promise的狀態, 而不管其是否處理成功.

6.7 axios 的使用

6.7.1 restful API的使用

在后續的前后端分離式開發中,常見的增刪改查不再是純粹的GET+POST的兩種請求方式,而是分的更加細化:

  • GET:查詢請求類型
    • 取全部的數據(列表)
    • 取單個的數據(詳情)
  • POST:新增請求類型
    • 新增是不帶條件
  • PUT:修改請求類型
    • 修改是要條件的
    • 修改條件的傳遞是通過地址欄傳遞的(restful規范)
    • 修改的數據主體是通過請求體傳遞的(請求體發送方式與post一致)
  • DELETE:刪除請求類型
    • 刪除需要條件的
    • 條件通過地址欄傳遞的

這種對請求方法(請求動詞)約束的規范叫做restFul規范(整理什么是restful)。該規范不是硬性要求,但是接口設計的時候一般都會遵守,其規范的不僅僅是請求方式,在請求地址形式、響應狀態碼等方面也存在規范要求(具體的要求項目時再說)。

6.7.2 axios

Axios 是一個基于 promise 的 HTTP 庫,可以用在瀏覽器和 node.js 中。axios對ajax進行了封裝,返回promise對象,比ajax更簡潔好用

特性

  • 從瀏覽器中創建 XMLHttpRequests
  • 從 node.js 創建 http 請求
  • 支持 Promise API
  • 攔截請求和響應 ***
  • 轉換請求數據和響應數據
  • 取消請求
  • 自動轉換 JSON 數據
  • 客戶端支持防御 XSRF

6.7.1 axios.get

axios.get("http://www.51houniao.com/product/product/guessYouLike").then(res => {console.log(res);//渲染頁面var str = "";res.data.forEach((item, index) => {str += `<li>${item.proTitle}</li>`;})document.querySelector('#like').innerHTML = str;})

6.7.2 axios.post

//參數: 參數一:url地址;參數二: 傳給服務器的json對象數據axios.post("http://www.51houniao.com/requirement/request/getMatchedProducts", {desc: false,orderBy: "outtime",pageSize: 100,product_type: 2,}).then(res => {console.log(res);//渲染頁面var str = "";res.data.matchedProducts.forEach((item, index) => {str += `<li>${item.pro_title}</li>`;})document.querySelector('#like').innerHTML = str;})

6.7.3 //支持多個并發請求

        function getData1() {return axios.get("./json/01.json");}function getData2() {return axios.get("./json/02.json");}//axios的并發請求axios.all([getData1(), getData2()]).then(res => {console.log(res);var mydata = [];res.forEach((item, index) => {mydata = mydata.concat(item.data.matchedProducts);})console.log(mydata);//渲染})

6.7.4 axios 通用寫法

       axios({method: 'get',url: './json/01.json',data: {}}).then(res => {console.log(res);})

6.7.5 請求方法的別名

為方便起見,為所有支持的請求方法提供了別名

axios.request(config)
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.options(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])
注意

在使用別名方法時, urlmethoddata 這些屬性都不必在配置中指定。

6.7.6 攔截器

在請求或響應被 thencatch 處理前攔截它們。

        var aa = 123;try{alert(a);}catch(e){  //exceptionalert(e);  // 捕獲異常}alert(666);//then
axios.get(url).then(res=>{...
})

參考:http://www.axios-js.com/zh-cn/docs/#axios-API

6.8 async await

async await 的語法糖 es7之后才出現 和 promise 、generator都有一定的關系,

async-awaitpromisegenerator的語法糖。只是為了讓我們書寫代碼時更加流暢,當然也增強了代碼的可讀性。

async 表示異步,屬于異步操作的關鍵字


三頁數據順序執行使用 async await


七.http協議 https協議 websocket協議

7.1 超文本傳輸協議

客戶端與服務器之間要實現網頁內容的傳輸,則通信的雙方必須遵守網頁內容的傳輸協議。

網頁內容又叫做超文本,因此網頁內容的傳輸協議又叫做超文本傳輸協議(HyperText Transfer Protocol) ,簡稱 HTTP 協議。

請添加圖片描述

7.2 HTTP請求消息的組成部分

由于 HTTP 協議屬于客戶端瀏覽器和服務器之間的通信協議。因此,客戶端發起的請求叫做 HTTP 請求,客戶端發送到服務器的消息,叫做 HTTP 請求消息。

注意:HTTP 請求消息又叫做 HTTP 請求報文。

HTTP 請求消息由請求行(request line)、請求頭部( header ) 、空行 和 請求體 4 個部分組成。

請添加圖片描述

  • a.請求行由請求方式、URL 和 HTTP 協議版本 3 個部分組成,他們之間使用空格隔開。

請添加圖片描述

請添加圖片描述

  • b. 請求頭部

請求頭部用來描述客戶端的基本信息,從而把客戶端相關的信息告知服務器。比如:
User-Agent 用來說明當前是什么類型的瀏覽器;
Content-Type 用來描述發送到服務器的數據格式;
Accept 用來描述客戶端能夠接收什么類型的返回內容;
Accept-Language 用來描述客戶端期望接收哪種人類語言的文本內容。
請求頭部由多行 鍵/值對 組成,每行的鍵和值之間用英文的冒號分隔。
在這里插入圖片描述

關于更多請求頭字段的描述,可以查看 MDN 官方文檔:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers

  • c. 請求體

請求體中存放的,是要通過 POST 方式提交到服務器的數據。

注意:只有 POST 請求才有請求體,GET 請求沒有請求體!

7.3 HTTP響應消息

響應消息就是服務器響應給客戶端的消息內容,也叫作響應報文。

HTTP響應消息由狀態行、響應頭部、空行 和 響應體 4 個部分組成,如下圖所示:
在這里插入圖片描述

  • a. 狀態行

狀態行由 HTTP 協議版本、狀態碼和狀態碼的描述文本 3 個部分組成,他們之間使用空格隔開;
在這里插入圖片描述
在這里插入圖片描述

  • b. 響應頭部

響應頭部用來描述服務器的基本信息。響應頭部由多行 鍵/值對 組成,每行的鍵和值之間用英文的冒號分隔。
在這里插入圖片描述
在這里插入圖片描述

關于更多響應頭字段的描述,可以查看 MDN 官方文檔:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers

  • c. 響應體

響應體中存放的,是服務器響應給客戶端的資源內容。
在這里插入圖片描述
在這里插入圖片描述

7.4 HTTP請求方法

HTTP 請求方法,屬于 HTTP 協議中的一部分,請求方法的作用是:用來表明要對服務器上的資源執行的操作。最常用的請求方法是 GET 和 POST。

請添加圖片描述

7.5 HTTP響應狀態碼

HTTP 響應狀態碼(HTTP Status Code),也屬于 HTTP 協議的一部分,用來標識響應的狀態。
響應狀態碼會隨著響應消息一起被發送至客戶端瀏覽器,瀏覽器根據服務器返回的響應狀態碼,就能知道這次 HTTP 請求的結果是成功還是失敗了。

HTTP 狀態碼由三個十進制數字組成,第一個十進制數字定義了狀態碼的類型,后兩個數字用來對狀態碼進行細分。
HTTP 狀態碼共分為 5 種類型:

請添加圖片描述

完整的 HTTP 響應狀態碼,可以參考 MDN 官方文檔 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status

常用的狀態碼:

2**

在這里插入圖片描述

3**
在這里插入圖片描述

4** 客戶端錯誤,很大幾率西藥前端工程師 出手

在這里插入圖片描述405 請求方式不對
415 請求時傳送給服務器的參數不對

5**

在這里插入圖片描述

7.6 https協議

HTTPS (全稱:Hyper Text Transfer Protocol over SecureSocket Layer),是以安全為目標的 HTTP 通道,在HTTP的基礎上通過傳輸加密和身份認證保證了傳輸過程的安全性 [1] 。HTTPS 在HTTP 的基礎下加入SSL,HTTPS 的安全基礎是 SSL,因此加密的詳細內容就需要 SSL。 HTTPS 存在不同于 HTTP 的默認端口及一個加密/身份驗證層(在 HTTP與 TCP 之間)。這個系統提供了身份驗證與加密通訊方法。它被廣泛用于萬維網上安全敏感的通訊,例如交易支付等方面

HTTP的缺點

HTTP雖然使用極為廣泛, 但是卻存在不小的安全缺陷, 主要是其數據的明文傳送和消息完整性檢測的缺乏, 而這兩點恰好是網絡支付, 網絡交易等新興應用中安全方面最需要關注的 [3] 。

關于 HTTP的明文數據傳輸, 攻擊者最常用的攻擊手法就是網絡嗅探, 試圖從傳輸過程當中分析出敏感的數據, 例如管理員對 Web 程序后臺的登錄過程等等, 從而獲取網站管理權限, 進而滲透到整個服務器的權限。即使無法獲取到后臺登錄信息, 攻擊者也可以從網絡中獲取普通用戶的隱秘信息, 包括手機號碼, 身份證號碼, 信用卡號等重要資料, 導致嚴重的安全事故。進行網絡嗅探攻擊非常簡單, 對攻擊者的要求很低。使用網絡發布的任意一款抓包工具, 一個新手就有可能獲取到大型網站的用戶信息 [3] 。

另外,HTTP在傳輸客戶端請求和服務端響應時, 唯一的數據完整性檢驗就是在報文頭部包含了本次傳輸數據的長度, 而對內容是否被篡改不作確認。 因此攻擊者可以輕易的發動中間人攻擊, 修改客戶端和服務端傳輸的數據, 甚至在傳輸數據中插入惡意代碼, 導致客戶端被引導至惡意網站被植入木馬 [3] 。

改進目標

HTTPS 協議是由 HTTP 加上 TLS/SSL 協議構建的可進行加密傳輸、身份認證的網絡協議,主要通過數字證書、加密算法、非對稱密鑰等技術完成互聯網數據傳輸加密,實現互聯網傳輸安全保護。設計目標主要有三個。

(1)數據保密性:保證數據內容在傳輸的過程中不會被第三方查看。就像快遞員傳遞包裹一樣,都進行了封裝,別人無法獲知里面裝了什么 [4] 。

(2)數據完整性:及時發現被第三方篡改的傳輸內容。就像快遞員雖然不知道包裹里裝了什么東西,但他有可能中途掉包,數據完整性就是指如果被掉包,我們能輕松發現并拒收 [4] 。

(3)身份校驗安全性:保證數據到達用戶期望的目的地。就像我們郵寄包裹時,雖然是一個封裝好的未掉包的包裹,但必須確定這個包裹不會送錯地方,通過身份校驗來確保送對了地方 [4] 。

HTTPS協議的改進

雙向的身份認證

客戶端和服務端在傳輸數據之前,會通過基于X.509證書對雙方進行身份認證 。具體過程如下 [3] :

客戶端發起 SSL 握手消息給服務端要求連接。

服務端將證書發送給客戶端。

客戶端檢查服務端證書,確認是否由自己信任的證書簽發機構簽發。 如果不是,將是否繼續通訊的決定權交給用戶選擇 ( 注意,這里將是一個安全缺陷 )。如果檢查無誤或者用戶選擇繼續,則客戶端認可服務端的身份。

服務端要求客戶端發送證書,并檢查是否通過驗證。失敗則關閉連接,認證成功則從客戶端證書中獲得客戶端的公鑰,一般為1024位或者 2048位。到此,服務器客戶端雙方的身份認證結束,雙方確保身份都是真實可靠的。

數據傳輸的機密性

客戶端和服務端在開始傳輸數據之前,會協商傳輸過程需要使用的加密算法。 客戶端發送協商請求給服務端, 其中包含自己支持的非對稱加密的密鑰交換算法 ( 一般是RSA), 數據簽名摘要算法 ( 一般是SHA或者MD5) , 加密傳輸數據的對稱加密算法 ( 一般是DES),以及加密密鑰的長度。 服務端接收到消息之后,選中安全性最高的算法,并將選中的算法發送給客戶端,完成協商。客戶端生成隨機的字符串,通過協商好的非對稱加密算法,使用服務端的公鑰對該字符串進行加密,發送給服務端。 服務端接收到之后,使用自己的私鑰解密得到該字符串。在隨后的數據傳輸當中,使用這個字符串作為密鑰進行對稱加密 [3] 。

防止重放攻擊

SSL使用序列號來保護通訊方免受報文重放攻擊。這個序列號被加密后作為數據包的負載。在整個SSL握手中,都有一個唯一的隨機數來標記SSL握手。 這樣防止了攻擊者嗅探整個登錄過程,獲取到加密的登錄數據之后,不對數據進行解密, 而直接重傳登錄數據包的攻擊手法。

可以看到,鑒于電子商務等安全上的需求,HTTPS對比HTTP,在安全方面已經取得了極大的增強。總結來說,HTTPS的改進點在于創造性的使用了非對稱加密算法,在不安全的網路上,安全的傳輸了用來進行對稱加密的密鑰,綜合利用了非對稱加密的安全性和對稱加密的快速性 [3] 。

HTTPS與HTTP原理區別

HTTPS 主要由兩部分組成:HTTP + SSL / TLS,也就是在 HTTP 上又加了一層處理加密信息的模塊。服務端和客戶端的信息傳輸都會通過 TLS 進行加密,所以傳輸的數據都是加密后的數據。

HTTP 原理

① 客戶端的瀏覽器首先要通過網絡與服務器建立連接,該連接是通過TCP 來完成的,一般 TCP 連接的端口號是80。 建立連接后,客戶機發送一個請求給服務器,請求方式的格式為:統一資源標識符(URL)、協議版本號,后邊是 MIME 信息包括請求修飾符、客戶機信息和許可內容 [2] 。

② 服務器接到請求后,給予相應的響應信息,其格式為一個狀態行,包括信息的協議版本號、一個成功或錯誤的代碼,后邊是 MIME 信息包括服務器信息、實體信息和可能的內容 [2] 。

HTTPS 原理

① 客戶端將它所支持的算法列表和一個用作產生密鑰的隨機數發送給服務器

② 服務器從算法列表中選擇一種加密算法,并將它和一份包含服務器公用密鑰的證書發送給客戶端;該證書還包含了用于認證目的的服務器標識,服務器同時還提供了一個用作產生密鑰的隨機數

③ 客戶端對服務器的證書進行驗證(有關驗證證書,可以參考數字簽名),并抽取服務器的公用密鑰;然后,再產生一個稱作 pre_master_secret 的隨機密碼串,并使用服務器的公用密鑰對其進行加密(參考非對稱加 / 解密),并將加密后的信息發送給服務器

④ 客戶端與服務器端根據 pre_master_secret 以及客戶端與服務器的隨機數值獨立計算出加密和 MAC密鑰(參考 DH密鑰交換算法

⑤ 客戶端將所有握手消息的 MAC 值發送給服務器

⑥ 服務器將所有握手消息的 MAC 值發送給客戶端

優缺點

優點
  1. 使用 HTTPS 協議可認證用戶和服務器,確保數據發送到正確的客戶機和服務器
  2. HTTPS 協議是由 SSL+HTTP構建的可進行加密傳輸、身份認證的網絡協議,要比 HTTP安全,可防止數據在傳輸過程中被竊取、改變,確保數據的完整性
  3. HTTPS 是現行架構下最安全的解決方案,雖然不是絕對安全,但它大幅增加了中間人攻擊的成本
缺點
  1. 相同網絡環境下,HTTPS 協議會使頁面的加載時間延長近 50%,增加 10%到 20%的耗電。此外,HTTPS 協議還會影響緩存,增加數據開銷和功耗
  2. HTTPS 協議的安全是有范圍的,在黑客攻擊、拒絕服務攻擊和服務器劫持等方面幾乎起不到什么作用
  3. 最關鍵的是,SSL 證書的信用鏈體系并不安全。特別是在某些國家可以控制 CA 根證書的情況下,中間人攻擊一樣可行
  4. 成本增加。部署 HTTPS 后,因為 HTTPS 協議的工作要增加額外的計算資源消耗,例如 SSL 協議加密算法和 SSL 交互次數將占用一定的計算資源和服務器成本。在大規模用戶訪問應用的場景下,服務器需要頻繁地做加密和解密操作,幾乎每一個字節都需要做加解密,這就產生了服務器成本。隨著云計算技術的發展,數據中心部署的服務器使用成本在規模增加后逐步下降,相對于用戶訪問的安全提升,其投入成本已經下降到可接受程度

7.7 http1.0 和 2.0的區別

7.7.1 1.0和1.1 的區別

HTTP1.0最早在網頁中使用是在1996年,那個時候只是使用一些較為簡單的網頁上和網絡請求上,而HTTP1.1則在1999年才開始廣泛應用于現在的各大瀏覽器網絡請求中,同時HTTP1.1也是當前使用最為廣泛的HTTP協議。 主要區別主要體現在:

  1. 緩存處理,在HTTP1.0中主要使用header里的If-Modified-Since,Expires來做為緩存判斷的標準,HTTP1.1則引入了更多的緩存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供選擇的緩存頭來控制緩存策略。
  2. 帶寬優化及網絡連接的使用,HTTP1.0中,存在一些浪費帶寬的現象,例如客戶端只是需要某個對象的一部分,而服務器卻將整個對象送過來了,并且不支持斷點續傳功能,HTTP1.1則在請求頭引入了range頭域,它允許只請求資源的某個部分,即返回碼是206(Partial Content),這樣就方便了開發者自由的選擇以便于充分利用帶寬和連接。
  3. 錯誤通知的管理,在HTTP1.1中新增了24個錯誤狀態響應碼,如409(Conflict)表示請求的資源與資源的當前狀態發生沖突;410(Gone)表示服務器上的某個資源被永久性的刪除。
  4. Host頭處理,在HTTP1.0中認為每臺服務器都綁定一個唯一的IP地址,因此,請求消息中的URL并沒有傳遞主機名(hostname)。但隨著虛擬主機技術的發展,在一臺物理服務器上可以存在多個虛擬主機(Multi-homed Web Servers),并且它們共享一個IP地址。HTTP1.1的請求消息和響應消息都應支持Host頭域,且請求消息中如果沒有Host頭域會報告一個錯誤(400 Bad Request)。
  5. 長連接,HTTP 1.1支持長連接(PersistentConnection)和請求的流水線(Pipelining)處理,在一個TCP連接上可以傳送多個HTTP請求和響應,減少了建立和關閉連接的消耗和延遲,在HTTP1.1中默認開啟Connection: keep-alive,一定程度上彌補了HTTP1.0每次請求都要創建連接的缺點。

7.7.2 HTTP2.0和HTTP1.X相比的新特性

  • 新的二進制格式(Binary Format),HTTP1.x的解析是基于文本。基于文本協議的格式解析存在天然缺陷,文本的表現形式有多樣性,要做到健壯性考慮的場景必然很多,二進制則不同,只認0和1的組合。基于這種考慮HTTP2.0的協議解析決定采用二進制格式,實現方便且健壯。
  • 多路復用(MultiPlexing),即連接共享,即每一個request都是是用作連接共享機制的。一個request對應一個id,這樣一個連接上可以有多個request,每個連接的request可以隨機的混雜在一起,接收方可以根據request的 id將request再歸屬到各自不同的服務端請求里面。
  • header壓縮,如上文中所言,對前面提到過HTTP1.x的header帶有大量信息,而且每次都要重復發送,HTTP2.0使用encoder來減少需要傳輸的header大小,通訊雙方各自cache一份header fields表,既避免了重復header的傳輸,又減小了需要傳輸的大小。
  • 服務端推送(server push),同SPDY一樣,HTTP2.0也具有server push功能。 websocket

參看: https://www.cnblogs.com/heluan/p/8620312.html

7.8 websocket 流程

WebSocket 協議在2008年誕生,2011年成為國際標準。所有瀏覽器都已經支持了。

它的最大特點就是,服務器可以主動向客戶端推送信息,客戶端也可以主動向服務器發送信息,是真正的雙向平等對話,屬于服務器推送技術的一種。

其他特點包括:

(1)建立在 TCP 協議之上,服務器端的實現比較容易。

(2)與 HTTP 協議有著良好的兼容性。默認端口也是80和443,并且握手階段采用 HTTP 協議,因此握手時不容易屏蔽,能通過各種 HTTP 代理服務器。

(3)數據格式比較輕量,性能開銷小,通信高效。

(4)可以發送文本,也可以發送二進制數據。

(5)沒有同源限制,客戶端可以與任意服務器通信。

(6)協議標識符是ws(如果加密,則為wss),服務器網址就是 URL。

簡單實例:


var ws = new WebSocket("wss://echo.websocket.org");ws.onopen = function(evt) { console.log("Connection open ..."); ws.send("Hello WebSockets!");
};ws.onmessage = function(evt) {console.log( "Received Message: " + evt.data);ws.close();
};ws.onclose = function(evt) {console.log("Connection closed.");
};      
  • socket.io:功能強大,支持集成websocket服務器端和Express3框架與一身。

參看:

http://www.ruanyifeng.com/blog/2017/05/websocket.html

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://808629.com/122342.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 86后生记录生活 Inc. 保留所有权利。

底部版权信息