哈尔滨建设规划局网站,山东诚信工程建设监理有限公司网站,猪肉价格最新消息,安卓app开发多少钱什么是跨域 注#xff1a;本文完整示例地址先来说一个概念就是同源#xff0c;同源指的是协议#xff0c;端口#xff0c;域名全部相同。 同源策略#xff08;Same origin policy#xff09;是一种约定#xff0c;它是浏览器最核心也最基本的安全功能#xff0c;如果缺… 什么是跨域 注本文完整示例地址先来说一个概念就是同源同源指的是协议端口域名全部相同。 同源策略Same origin policy是一种约定它是浏览器最核心也最基本的安全功能如果缺少了同源策略则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的浏览器只是针对同源策略的一种实现。 同源策略是处于对用户安全的考虑如果非同源就会受到以下限制 cookie不能读取dom无法获得ajax请求不能发送但是事实是经常需要借助非同源来提供数据所以就需要进行跨域请求。 JSONP JSONP是指JSON PaddingJSONP是一种非官方跨域数据交换协议由于script的src属性可以跨域请求所以JSONP利用的就是浏览器的这个“漏洞”需要通信时动态的插入一个script标签。请求的地址一般带有一个callback参数假设需要请求的地址为http://localhost:666?callbackshow服务端返回的代码一般是show(数据)的JSON数据而show函数恰恰是前台需要用这个数据的函数。JSONP非常的简单易用自动补全API利用的就是JSONP下面来看一个例子 // 前端请求代码
function jsonp (callback) {var script document.createElement(script),url http://localhost:666?callback${callback};script.setAttribute(src, url);document.querySelector(head).appendChild(script);
}
function show (data) {console.log(学生姓名为${data.name}年龄为${data.age}性别为${data.sex});
}
jsonp(show);
// 后端响应代码
const student {name: zp1996,age: 20,sex: male
};
var callback url.parse(req.url, true).query.callback;
res.writeHead(200, {Content-Type: application/json;charsetutf-8
});
res.end(${callback}(${JSON.stringify(student)})); JSONP虽说简单易用但是有一个很大问题那就是JSONP只能进行get请求 CORS CORS(跨域资源共享)是由W3C制定的跨站资源分享标准可以让AJAX实现跨域访问。想要了解跨域的话首先需要了解下简单请求 请求方式为GET或者POST 假若请求是POST的话Content-Type必须为下列之一 application/x-www-form-urlencodedmultipart/form-datatext/plain不含有自定义头类似于segmentfault自定义的头X-Hit对于简单请求的跨域只需要进行一次http请求 function ajaxPost (url, obj, header) {return new Promise((resolve, reject) {var xhr new XMLHttpRequest(),str ,keys Object.keys(obj);for (var i 0, len keys.length; i len; i) {str ${keys[i]}${obj[keys[i]]};}str str.substring(0, str.length - 1);xhr.open(post, url);xhr.setRequestHeader(Content-Type,application/x-www-form-urlencoded);if (header instanceof Object) {for (var k in header) xhr.setRequestHeader(k, header[k]);}xhr.send(str);xhr.onreadystatechange function () {if (xhr.readyState 4) {if (xhr.status 200 xhr.status 300 || xhr.status 304) {resolve(xhr.responseText);} else {reject();}}}});
}
ajaxPost(http://localhost:666?pagecors, {name: zp1996,age: 20,sex: male
})
.then((text) { console.log(text); }, () { console.log(请求失败); });// 后端处理
var postData ;
// 注释下下面示例后台代码补充在此处
req.on(data, (data) {postData data;
});
req.on(end, () {postData querystring.parse(postData);res.writeHead(200, {Access-Control-Allow-Origin: *,Content-Type: application/json;charsetutf-8});if (postData.name student.name Number(postData.age) student.age postData.sex student.sex) {res.end(yeah${postData.name} is a good boy~);} else {res.end(Noa bad boy~);}
});打开控制台观察可以发现Network只是发出了一次请求但是对于非简单请求来说需要两次http请求在真正的请求之前需要进行一次预请求下图是进行一次预请求的请求/响应 观察响应头可以发现需要多出了两个响应头 Access-Control-Allow-Headers用来指明在实际的请求中可以使用那些自定义的http请求头。Access-Control-Max-Age用来指定此次预请求的结果的有效期在有效期内则不会发出预请求有点像缓存的感觉。当然还有诸如好多这样的响应头请大家自行搜索了解这里就不再过多介绍下面来看下对于非简单请求跨域的代码处理 // 前端请求代码
ajaxPost(http://localhost:666?pagecors, {name: zp1996,age: 20,sex: male
}, { X-author: zp1996 })
.then((text) { console.log(text); }, () { console.log(请求失败); });// 后端处理补充在简单请求代码注释处
if (req.method OPTIONS) {res.writeHead(200, {Access-Control-Max-Age: 3000,Access-Control-Allow-Origin: *,Access-Control-Allow-Headers: X-author,Content-Type: application/json;charsetutf-8}); res.end();return void 0;
} CSS Text Transformation 既然可以利用script的“漏洞”来进行JSONP跨域那么是不是也可以利用css样式写可以进行跨域请求来进行跨域呢答案肯定是yes利用css还有一个好处那就是当被注入攻击脚本时css尽管被注入也不会引起什么大的安全问题顶多也就是把页面的样式给改变而js被注入的话cookie就有可能被盗取等一系列安全问题出现。大牛已经将其做的非常完善大家可以去star王集鹄zswangCSST这里我就把我所理解给大家简单的分享下 // 前端代码
const id csst,ele document.querySelector(#${id}),head document.querySelector(head);
function getStyle (ele, prop) {return getComputedStyle(ele, ).getPropertyValue(prop);
}
function loadCss (url) {return new Promise((resolve) {const link document.createElement(link);link.setAttribute(rel, stylesheet);link.setAttribute(type, text/css);link.setAttribute(href, url);ele.addEventListener(webkitAnimationStart, function () {resolve(getStyle(ele, content));});head.appendChild(link);});
}
loadCss(http://localhost:666?pagedata.cssid${id}).then((data) {console.log(data);
});// 后端代码
function cssData (id) {return keyframes a{from{}to{color: red;}}#${id} {content: 这种是很好但是只能传输文本啊;animation: a 2s;};
}
res.writeHead(200, {Content-Type: text/css
});
res.end(cssData(query.id));通过代码可以看出这种实现方式是靠元素的content来拿接收到的数据所以传输的只能是文本。至于为什么要返回动画是因为不利用动画无法来对css脚本加载进行监测也就无法进行回调由于谷歌/火狐不支持link的onload和onreadychange所以利用animationstart事件。 window.postMessage window.postMessage 是一个安全的跨源通信的方法。一般情况下当且仅当执行脚本的页面使用相同的协议通常都是 http、相同的端口http默认使用80端口和相同的 host两个页面的 document.domain 的值相同时才允许不同页面上的脚本互相访问。 window.postMessage 提供了一个可控的机制来安全地绕过这一限制当其在正确使用的情况下。 window.postMessage解决的不是浏览器与服务器之间的交互解决的是浏览器不同的窗口之间的通信问题可以做的就是同步两个网页当然这两个网页应该是属于同一个基础域名。 // 发送端代码
var domain http://localhost,index 1,target window.open(${domain}/postmessage-target.html);
function send () {setInterval(() {target.postMessage(第${index}次数据发送, domain);}, 1000);
}
send();
// 接受端代码
div idtest没有数据过来啊div
script typetext/javascriptvar test document.querySelector(#test);window.addEventListener(message, e {if (e.origin ! http://localhost) {return void 0;}test.innerText e.data;});
/script上述代码实现了向一个页面向另一个发送数据但是这么写往往有着一些“危险”需要知道的是postMessage是向document对象中网络连接有时会很慢可能会出现些问题所以最好的方式是接受页面已经开始加载了这时发送一个消息给发送端发送端在开始向接收端发送数据。改进下 // 发送端添加代码
window.addEventListener(message, (e) {if (e.data ok)send();else console.log(e.data);
});// 接受端的head里面加上script标签
script typetext/javascriptopener.postMessage(ok, opener.domain);
/script window.name window.name 的美妙之处name 值在不同的页面甚至不同域名加载后依旧存在并且可以支持非常长的 name 值2MB 这个方式我基本上没有用过所以没有过多的发言权大家想了解这个技术的话可以通过怿飞圆心使用 window.name 解决跨域问题圆心大神解释的非常透彻。 document.domain 将子域和主域的document.domain设为同一个主域前提条件 这两个域名必须属于同一个基础域名而且所用的协议端口都要一致否则无法利用document.domain进行跨域