1. 程式人生 > >【通訊】前端中的幾類資料互動方式

【通訊】前端中的幾類資料互動方式

資料互動

主要從下面幾類講解:

  • 1、http協議
  • 2、form表單
  • 3、ajax–官方提供,單向,浪費流量,預設不能跨域(不能從a.com讀取b.com下的東西),但有跨域的方法
  • 4、jsonp ——民間,支援跨域,不推薦,破壞了http自身的安全協議
  • 5、WebSocket——H5新特性,雙工(雙向)

http協議

  • 1、無狀態
  • 2、連線過程:連線、接收、傳送(三次握手)
  • 3、訊息報文2部分:頭部(header)<=32k、體部(body)<=2G

http快取設定方式:

  • 1、隨機數:一種“野路子”寫法
  • 2、快取原理 - 頭部:Cache-control、 Date、Expires

http與https:

  • https在http之上加上安全特性
  • https需要證書:證明你自己身份,有相應的頒發機構,一般分兩種:一種是第三方頒佈的,一種是自己頒佈的 Let’s Encrypt免費
  • 生成證書的時候,就會生成公鑰

http版本

  • http1.0 面向短連線:請求之後連線就斷開
  • http1.1 主流 長連線——keep alive
  • http2.0 還未大規模應用推廣

Http2.0

  • 強制使用https
  • 效能高:面向流、頭壓縮、多路複用
  • 雙向通訊——伺服器推送
  • 未來趨勢

form

  • ajax\jsonp都是對Form的模擬

  • action : 提交到哪

  • method: GET/POST/PUT/DELETE/HEAD

  • GET:把資料放在url裡面傳輸 ,資料量很小,會快取(主要便於獲取,下次獲取時就更快),看得見

  • POST: 放在Body裡 , 資料量大,不會快取 ,看不見

  • DELETE:刪除

  • PUT:傳送

  • HEAD:讓伺服器只發送頭回來就行(不需要內容),form發不出head請求;程式碼可以發head請求,伺服器會只返回一個Response Headers;常用於測試伺服器是否存在

  • enctype :

    • application/x-www-form-urlencoded 預設、適合傳送小資料 形式:名字=值&名字=值…
    • multipart/form-data 上傳檔案 、分塊、適合大資料(<=1G)
    • text/plain 純文字,不常用
  • formData

  • RESTFUL https://www.imooc.com/learn/811

ajax原理

  • XMLHttpRequest物件,不相容IE6

    //1、建立物件
    let xhr = new XMLHttpRequest();
    
    //2、連線
    xhr.open('GET','url',true); //true非同步,false同步
    //3、傳送
    xhr.send('body資料');
    //4、接收
    xhr.onreadystatechange = function(){
    //onreadystatechange分多次執行
    //readyState當前通訊狀態值:
    //1、 0 初始狀態:xhr物件剛剛建立完
    //2、 1 連線:連線到伺服器
    //3、 2 傳送請求:剛剛Send完
    //4、 3 接收完成:頭接收完了
    //5、 4 接收完成:體接收完了
    //status--http狀態碼,表明通訊結果
    //1xx 訊息
    //2xx,304 成功
    //3xx  重定向 301 Moved Permanently(永久重定向,下回不會再請求這個伺服器) 302-臨時重定向(下回依然會請求這個伺服器) 304-Not Modified(date 快取未過期、快取過期)
    //4xx  請求錯誤,主要錯誤原因在客戶端
    //5xx  服務端錯誤
    //6xx+ 自定義
    
    if(xhr.readyState==4){
    		if(xhr.status>=200&&xhr.status<300||xhr.status==304){
    			//success
    			console.log(xhr.response)
    			//xhr.response
    			//xhr.responseText 以文字方式返回資料
    			//xhr.responseURL 
    			//xhr.responseXML  以XML方式返回資料
    			
    			let arr = eval('('+xhr.responseText+')') //解析方式1,不安全
    			let json=null;
    			try{
    				json = JSON.parse(xhr.respinseText) //解析成json
    			}catch(e){
    				json = eval('('+xhr.responseText+')') 
    			}
    			
    			
    		}else {
    			//failed
    		}
    }
    }
    

重定向:
例子:

安全:

  • 前端沒有大的安全性可言,後端才有;
  • xss – 跨站指令碼攻擊,別人把js程式碼放在你的程式碼上執行
    • DNS汙染,如運營商
    • 自己造成

本節關鍵:

Ajax2.0

  • 相容IE10+
  • FormData(容器): set()、get()、append()、delete()…等
  • 檔案上傳,依賴FormData;上傳進度監控 xhr.upload.onload/onprogress;
  • CORS跨域(跨域資源共享)
  • Ajax長連線(已被WebSocket替代)
  • xhr.send(formData)\xhr.send(Blob)\xhr.send(Buffer) ,Blob\Buffer二進位制資料

FormData

//FormData 一種容器
//formData.set('name',value)
<input type="button" value="ajax請求" id="btn1">
    <script>
        window.onload = function() {
            var oBtn = document.getElementById('btn1');
            oBtn.onclick= function(){
                var formData = new FormData();
                formData.set('a',12);
                formData.set('b',5);
                var xhr = new XMLHttpRequest();
                xhr.open('post','1.php',false);
                xhr.send(formData);
                xhr.onreadystatechange=function() {
                    if(xhr.readyState==4)
                        if(xhr.status>200&&xhr.status<300||xhr.status==304){
                            alert(xhr.responseText);
                        }else {
                            alert('error')
                        }
                    }
                }
            }
        }
    </script>

//FormData檔案上傳
//formData.set('name',<input type="file"/>);
//xhr.upload.onload 上傳完成
//xhr.upload.onprogress 進度變化
	 <input type="file"  id="f1"/>
    <input type="button" value="ajax請求" id="btn1">
    <script>
        window.onload = function() {
            var oBtn = document.getElementById('btn1');
            var oF1 = document.getElementById('f1');

            oBtn.onclick= function(){
                var formData = new FormData();
                formData.set('f1',oF1);

                var xhr = new XMLHttpRequest();

                //進度條
                xhr.upload.onload = function(){
                    console.log('上傳完成')
                }
                xhr.upload.onprogress = function(ev){
                    console.log(ev.loaded+'/'+ev.total);
                }

                xhr.open('post','1.php',false);
                xhr.send(formData);

                xhr.onreadystatechange=function() {
                    if(xhr.readyState==4){
                        
                        if(xhr.status>200&&xhr.status<300||xhr.status==304){
                            alert(xhr.responseText);
                        }else {
                            alert('error')
                        }
                    }
                }
            }
        }
    </script>

CORS 跨域

  • 跨域:域不同。域=協議+域名+埠

  • 瀏覽器+伺服器共同配合

瀏覽器:

<input type="file"  id="f1"/>
    <input type="button" value="ajax請求" id="btn1">
    <script>
        window.onload = function() {
            var oBtn = document.getElementById('btn1');
            var oF1 = document.getElementById('f1');

            oBtn.onclick= function(){
                var xhr = new XMLHttpRequest();
                xhr.open('post','http://localhost:8080',true);
                xhr.send();
                xhr.onreadystatechange=function() {
                    if(xhr.readyState==4){
                        alert(xhr.status);
                    }
                }
            }
        }
    </script>

伺服器 res.setHeader(‘Access-Control-Allow-Origin’,’*’);

const http = require('http');

let server = http.createServer(function(req,res){
    console.log(req.headers);
    let allowHosts = ['baidu.com','taobao.com','tmall.com']; //加判斷,過濾
    if(allowHost.indexOf(req.headers['origin'])!=-1){
        res.setHeader('Access-Control-Allow-Origin','*');  //伺服器推一個頭Access-Control-Allow-Origin會去
    }
    res.write('123');
    res.end();
})

server.listen(8080);

req.headers
在這裡插入圖片描述

jsonp跨域原理(逐漸被廢棄)

  • 例子(百度)

https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=qqvip&json=1&p=3&sid=1469_21089_27400_26350_22159&req=2&pbs=qq郵箱&csor=5&pwd=qqvio&cb=jQuery110204607003182369671_1540901339951&_=1540901339957

關鍵:

show({q:"qqvi",p:false,s:["qqvip","qqvip免費","qqvip郵箱","qq錄屏","qq表情怎麼匯入微信表情","qqvip卡通第二天就沒了","qq錄屏快捷鍵","qqvip8","qqvip有什麼用"]});

等價於:

//引用了一個外部指令碼
<script src="https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=qqvi&cb=show"></script>
<script>
function show(json){
	alert(json.s);  //s:["qqvip","qqvip免費","qqvip郵箱","qq錄屏","qq表情怎麼匯入微信表情","qqvip卡通第二天就沒了","qq錄屏快捷鍵","qqvip8","qqvip有什麼用"]
}
</script>

原理

  • 建立一個script標籤,給一個src 呼叫你的函式,如show()

jquery 中的jsonp功能

注意:jQuery中的jsonp不是Ajax

$(function(){
	$.ajax({
		url:'https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su',
		data: {wd:qqvip},
		dataType: 'jsonp',  //設定dataType為jsonp
		jsonp: 'cb',  //告訴JQuery這個回撥函式的名字叫cb,名字不固定,你也可以叫callback等等
		success(json){
			alert(json.s);
		},
		error(){
			alert('error');
		}
	})
});

示例

  • 客戶端修改
$.ajax({
	url:'http://localhost:8080/',
	data: {a:77,b:89},
	jsonp: 'callback',
	dataType: 'jsonp',
	success(num){
		alert(num)
	},
	error(e){
		alert(e);
	}
})
  • 服務端修改
const http = require('http')
const url = require('url')

let server = http.createServer(function(req,res){
	let {pathname,query} = url.parse(req.url,true);
	let {a,b,callback}=query;
	
	res.write('${callback}($(parseInt(a)+parseInt(b)))');
	res.end();
})

WebSocket:

  • 雙工
  • HTML5的,IE9+
  • 用的非常廣
  • socket.io庫,WebSocket相容庫
  • 安裝:npm install socket.io
  • 給前後臺使用
  • 基於/依賴於http
    http://socket.io
    //後端在node中使用:server.js 建立服務
const http = require('http');
const io = require('socket.io');

//1.建立一個http服務
let httpServer = http.createServer();
server.listen();

//2.然後建立一個webSocket 服務
let wsServer = io.listen(httpServer);//監聽一個http服務

wsServer.on('connection',function(sock){//連線事件,有連線時,會有一個sock物件
	sock.on('a',function(num1,num2){//接收
	    console.log('接到了瀏覽器傳送的資料:${num1} ,${num2}');
	})
}) 

//方法

  • sock.emit 傳送
  • sock.on 接收

//前端部分-做連線io.connect

<script src="../socket.io/socket.io.js"></script> //固定引入,實際上引入的是client.js
<script>
let sock = io.connect('ws://localhost:80080'); //前端也需要有一個sock物件,這樣前後端都有一個sock物件,可以進行通訊,"ws:"標識webSocket協議,告訴瀏覽器這是一個webSocket通訊
document.onclick = function(){
	sock.emit('a',12,5);//取一個名稱為“a”,自定義
}
</script>
//反之,服務端也可以進行emit,前端進行on

1、相容
2、二進位制資料

  • v8引擎
    預編譯:在編譯之前,先轉換為二進位制程式碼

  • nodejs

1、效能高
2、跟前臺配合方便
3、適合前端人員入門
4、適合中間層應用,不適合大型專案開發

在這裡插入圖片描述

fs.wirteHeader() => 寫header ,status=200
res.write() => 寫body
  • package.json

作用:

  • 不用把node_modules 拷貝到伺服器 ,只需拷貝package.json 然後再服務端只需npm i,就會下載需要的包

  • npm i XXX -D安裝xxx需要依賴的包 “devDependencies”

  • "scripts"中可以寫指令碼

  • 聊天室業務分析:

1、使用者註冊、登陸
2、發言-》其他人
3、離線訊息(離線的時候把資料存起來,等對方連線了,再從資料庫中取出來)

資料-》資料庫
1、使用者
2、訊息

單聊與群聊的區別:

  • 單聊是多個欄位(這個訊息是給誰了),群聊是廣播,沒有這個欄位,大家都可見

資料庫:
型別

  • 關係型資料庫——MySQL、Oracle,優點是支援複雜的功能;但缺點是相對其他型別,效能低
  • 檔案型資料庫——SQLite, 簡單;支撐不了龐大應用,沒法儲存特別多資料
  • 文件型資料庫——MongoDB,可以直接儲存物件本身;不夠嚴謹,效能偏低
  • 空間型資料庫——儲存座標、位置等GIS空間資料

NoSQL:
效能高

  • Redis、memcached、bigtable、hypertable
  • hive

庫——資料夾,管理用,本身不能存資料
表——檔案,存資料

型別:

  • 數字
    整數 tinyint(-128,127或0-255)、int(21億或43億)
    浮點數 float 8位、double 308位

  • 字串
    小字串 varchar(255bit)
    大字串 text(2G)

主鍵

  • 唯一
  • 效能高

多語言language.js

const http = require('http');

let server= http.createServer((req,res)=>{
	console.log()
	req.headers['accept-language'].split(':')[0].split(',')[0];
	switch(lang.toLowerCase()){
		case 'zh-cn':
			res.setHeader({location:'http://localhost/cn/'})
			res.writeHeader(302);
			break;
		default:
			res.setHeader({location:'http://localhost'})
			res.writeHeader(302);
			break;
	}
})
  • jQuery i18 外掛 多語言

原生WebSocket

  • WebSocket物件 let ws = new WebSocket();
  • let sock = ws.connect(‘ws://localhost:8080’);
  • on 方法
  • message時間

後端websocket