摘要:一同源策略用户浏览网站时难免需要将一些经常用到的信息,缓存在本地以提升交互体验,避免一些多余的操作。无法获得请求不能发送同源策略是必要的,但这些限制有时也会对一些合理的使用带来不便,这便引出了跨域通信的需求。
一、同源策略
用户浏览网站时难免需要将一些经常用到的信息,缓存在本地以提升交互体验,避免一些多余的操作。那么这些信息中难免有些就会涉及用户的隐私,怎么保证用户的信息不在多个站点之间共享,以达到可用的最小范围,这边引出了浏览器的同源策略。那么...
什么是同源策略?
同时满足以下三个条件的网页称为同源:
协议相同
域名相同
端口相同
非同源的网页将受到以下限制:
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) } } } } }
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/90313.html
摘要:一正则使用分类正则表达式后文简称为正则可划分出两种使用方式通过正则字面量与通过构造函数创建出来的正则对象,在不考虑访问正则对象属性的情况下,是等价的。匹配前一个表达式次或多次。 正则表达式在前端开发中,对于字符串处理任务来说,绝对是一件可以祭出的大杀器。同时对于前端开发人员来说也是一项基本技能,但若只是停留在能看懂,知道去哪查的阶段,那距离得心应手地运用差的可能不止一步两步。 行业总习...
摘要:从原型对象指向构造函数画一条带箭头的线。线上标注,表示该原型对象的构造函数等于。但除此之外,若构造函数所指的显示原型对象存在于的原型链上,结果也都会为。执行构造函数,并将指针绑定到新创建的对象上。 做前端开发有段时间了,遇到过很多坎,若是要排出个先后顺序,那么JavaScript的原型与对象绝对逃不出TOP3。 如果说前端是海,JavaScript就是海里的水 一直以来都想写篇文章梳理...
摘要:作为开发同学的小伙伴客户端的浏览器,有点小调皮还做了一个同源策略的限制,当我们的数据请求遇到不同源的情况下跨域,我们就得尝试其它的通信方法,不能一条道走到黑。 showImg(https://segmentfault.com/img/bVburZO?w=600&h=450); Web2.0以来,Ajax的出世,解决了传统表单提交页面跳转,闪烁白屏等问题。使得Web页面可以实现局部更新,...
阅读 2671·2019-08-30 15:55
阅读 1803·2019-08-30 15:53
阅读 2655·2019-08-29 18:38
阅读 927·2019-08-26 13:49
阅读 501·2019-08-23 15:42
阅读 3113·2019-08-22 16:33
阅读 1003·2019-08-21 17:59
阅读 1082·2019-08-21 17:11