摘要:一同源策略用戶瀏覽網站時難免需要將一些經常用到的信息,緩存在本地以提升交互體驗,避免一些多余的操作。無法獲得請求不能發送同源策略是必要的,但這些限制有時也會對一些合理的使用帶來不便,這便引出了跨域通信的需求。
一、同源策略
用戶瀏覽網站時難免需要將一些經常用到的信息,緩存在本地以提升交互體驗,避免一些多余的操作。那么這些信息中難免有些就會涉及用戶的隱私,怎么保證用戶的信息不在多個站點之間共享,以達到可用的最小范圍,這邊引出了瀏覽器的同源策略。那么...
什么是同源策略?
同時滿足以下三個條件的網頁稱為同源:
協議相同
域名相同
端口相同
非同源的網頁將受到以下限制:
Cookie、LocalStorage 和 IndexDB 無法讀取。
DOM 無法獲得
AJAX 請求不能發送
同源策略是必要的,但這些限制有時也會對一些合理的使用帶來不便,這便引出了跨域通信的需求。
二、跨域通信常見的跨域通信方式有如下集中:
JSONP
Hash
Postmessage
WebSocket
CORS
2.1 JSONPJSONP的原理是,首先客戶端動態添加一個元素,向服務器請求JSON數據,在請求的URL中添加search字段,指定回調函數名;服務器在收到請求后,會將數據放在指定名字的回調中傳回來。實現源碼:
/** * jsonp * @param {[type]} url [description] * @param {[type]} onsucess [description] * @param {[type]} onerror [description] * @param {[type]} charset [description] * @return {[type]} [description] */ const jsonp = function(url, onsucess, onerror, chartset){ let callbackName = getName("tmp_jsonp") window[callbackName] = function(){ if(onsucess && onsucess instanceof Function){ onsucess(arguments[0]) } } let script = createScript(url + "&callback=" + callbackName, charset) script.onload = script.onreadystatechange = function () { // script標簽加載完成(即jsonp請求完成)后移除創建的臨時標簽 if(!script.readyState || /loaded|complete/.test(script.readyState)){ script.onload = script.onreadystatechange = null // 移除該script的 DOM 對象 if (script.parentNode) { script.parentNode.removeChild(script) } window[callbackName] = null } } script.onerror = function () { if (onerror && util.isFunction(onerror)) { onerror(); } } document.getElementsByTagName("head")[0].appendChild(script) } /** * 獲取一個隨機的5位字符串 * @param {string} prefix [字符前綴] * @return {string} [字符集] */ const getName = function (prefix) { return prefix + Math.random().toString(36).replace(/[^a-z]+/g, "").substr(0, 5) } /** * 在頁面中創建script * @param {string} url [url] * @param {string} charset [字符集] * @return {string} [創建完成的script標簽] */ const createScript = function (url, charset) { let script = document.createElement("script") script.setAttribute("type", "text/javascript") charset && script.setAttribute("charset", charset) script.setAttribute("src", url) script.async = true return script }2.2 hash
hash方式主要用在內嵌iframe的父子窗口間的通信,原理是URL的#后部分的改變不會使頁面刷新。
(1)父窗口向子窗口發送數據
// 父窗口向子窗口發送數據 let src = orignURL + "#" + data document.getElementById("myIframe").src = src // 子窗口接收父窗口發送的數據 window.onhashchange = function(){ let message = window.location.hash ... }
(2)子窗口向父窗口發送數據,也同理
parent.location.herf = target + "#" + hash2.3 postmessage
首先創建目標窗口的window對象,然后通過該對象的postmessage方法傳遞數據,最后目標窗口通過監聽message事件來接受數據。
// 發送數據 let bWindow = window.open("http://b.com", "title") bWindow.postmessage("hello message", "http://b.com") // 接受數據 window.addEventListener("message", function(e){ // e.source 發送消息窗口的引用 // e.origin 發送消息的網址 // e.data 發送消息的內容 })
使用postmessage時需要注意的問題:
接受方打開了對message事件的響應,接收時需要對發送方進行驗證
發送消息時需要指定確定的接收方,不可指定為*進行群發
2.4 websocket// ws和wss的區別就是加不加密 let ws = new WebSocket("ws://xx.com") ws.onopen = function(e){} ws.onmessage = function(e){} ws.onclose = function(e){}2.5 CORS
可以簡單理解為跨域通信的ajax,需要瀏覽器和服務器同時支持,主要關鍵還是須在瀏覽器端進行配置。可參考CORS配置說明
三、前后端如何通信除了跨域通信,前端最常接觸的便是前后端通信,常見的前后端通信方式有以下三種:
ajax/fetch
websocket
cors
四、如何創建ajax 4.1 Vue框架實現ajaxVue是個沒什么入侵性的框架,所以在ajax方面可以有很多選擇:
使用原生js的XHR實現
引入jquery
Vue2.0官方推薦axios.js
fetch API
4.2 原生js實現ajax/** * 原生JS實現ajax * @param {object} options [傳入參數] * @return {[type]} [description] */ const ajax = function(options){ var opt = { url: "", type: "get", data: {}, success: function () {}, error: function () {}, } Object.assign(opt, options) if(opt.url){ let xhr = XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP") let data = opt.data, url = opt.url, type = opt.type.toUpperCase(), dataArr = [] for(let k in data){ dataArr.push(k + "=" + data[k]) } if(type == "GET"){ url = url + "?" + dataArr.join("&") xhr.open(type, url.replace(/?$/.g, ""), true) xhr.send() } if(type == "POST"){ xhr.open(type, url, true) xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded") xhr.send(dataArr.join("&")) } xhr.onload = () => { if(xhr.status === 200 || xhr.status === 304 || xhr.status === 206){ let res if(opt.success && opt.success instanceof Function){ res = xhr.responseText if(typeof res === "string"){ res = JSON.parse(res) opt.success.call(xhr, res) } } }else{ if(opt.error && opt.error instanceof Function){ opt.error.call(xhr, res) } } } } }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/90313.html
摘要:一正則使用分類正則表達式后文簡稱為正則可劃分出兩種使用方式通過正則字面量與通過構造函數創建出來的正則對象,在不考慮訪問正則對象屬性的情況下,是等價的。匹配前一個表達式次或多次。 正則表達式在前端開發中,對于字符串處理任務來說,絕對是一件可以祭出的大殺器。同時對于前端開發人員來說也是一項基本技能,但若只是停留在能看懂,知道去哪查的階段,那距離得心應手地運用差的可能不止一步兩步。 行業總習...
摘要:從原型對象指向構造函數畫一條帶箭頭的線。線上標注,表示該原型對象的構造函數等于。但除此之外,若構造函數所指的顯示原型對象存在于的原型鏈上,結果也都會為。執行構造函數,并將指針綁定到新創建的對象上。 做前端開發有段時間了,遇到過很多坎,若是要排出個先后順序,那么JavaScript的原型與對象絕對逃不出TOP3。 如果說前端是海,JavaScript就是海里的水 一直以來都想寫篇文章梳理...
摘要:作為開發同學的小伙伴客戶端的瀏覽器,有點小調皮還做了一個同源策略的限制,當我們的數據請求遇到不同源的情況下跨域,我們就得嘗試其它的通信方法,不能一條道走到黑。 showImg(https://segmentfault.com/img/bVburZO?w=600&h=450); Web2.0以來,Ajax的出世,解決了傳統表單提交頁面跳轉,閃爍白屏等問題。使得Web頁面可以實現局部更新,...
閱讀 2672·2019-08-30 15:55
閱讀 1804·2019-08-30 15:53
閱讀 2656·2019-08-29 18:38
閱讀 928·2019-08-26 13:49
閱讀 502·2019-08-23 15:42
閱讀 3114·2019-08-22 16:33
閱讀 1004·2019-08-21 17:59
閱讀 1082·2019-08-21 17:11