标签:frame html5 max-age host 防止 details ima 资源 无法
同源策略是一个重要的安全策略,它用于限制一个origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。
1.1何谓同源?
如果两个 URL 的 protocol、port (如果有指定的话)和 host 都相同的话,则这两个 URL 是同源。这个方案也被称为“协议/主机/端口元组”,或者直接是 “元组”。
下表给出了与 URL http://store.company.com/dir/page.html
的源进行对比的示例:
URL | 结果 | 原因 |
---|---|---|
http://store.company.com/dir2/other.html |
同源 | 只有路径不同 |
http://store.company.com/dir/inner/another.html |
同源 | 只有路径不同 |
https://store.company.com/secure.html |
失败 | 协议不同 |
http://store.company.com:81/dir/etc.html |
失败 | 端口不同 ( http:// 默认端口是80) |
http://news.company.com/dir/other.html |
失败 | 主机不同 |
随着互联网的发展,"同源政策"越来越严格。目前,如果非同源,共有三种行为受到限制。
(1) Cookie、LocalStorage 和 IndexDB 无法读取。
(2) DOM 无法获得。
(3) AJAX 请求不能发送。
虽然这些限制是必要的,但是有时很不方便,合理的用途也受到影响。
跨域问题是由于浏览器为了防止CSRF(跨站请求伪造)攻击,避免恶意攻击而带来的风险而采取的同源策略限制。当一个页面中使用XMLHTTPRequest对象发送HTTP请求时(XHR请求),必须保证当前页面和请求的对象是同源的
能实现跨域的技术还是比较多的,篇幅有限,这篇文章主要给大家带来:
JSONP的原理:静态资源请求不受同源策略影响。具体:浏览器只对XHR(XMLHttpRequest)请求有同源请求限制,而对script标签src属性、link标签ref属性和img标签src属性没有这种限制,利用这个“漏洞”就可以很好的解决跨域请求.
JSONP 由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数。回调
函数的名字一般是在请求中指定的。而数据就是传入回调函数中的JSON数据。
<script>
function jsoncallback(response){
console.log(response);
}
var script = document.createElement("script");
script.src = "https://me.kervi.cn/v1/datas/jsondata.php?callback=jsoncallback";
document.body.insertBefore(script, document.body.firstChild);
</script>
JSONP 是通过动态<script>
元素来使用的,使用时可以为src 属性指定一个跨域 URL。
总结:
script
标签的的src属性发送);<script>
元素新增了一个 onerror事件处理程序,但目前还没有得到任何浏览器支持。为此,开发人员不得不使用计时器检测指定时间内是否接收到了响应。但就算这样也不能尽如人意,毕竟不是每个用户上网的速度和带宽都一样。CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源服务器,发出XMLHttpRequest
请求,从而克服了AJAX只能同源使用的限制。它使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。
整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
在各种服务端代码实现如下:
// 根据不同语言规则,具体语法有所不同,此处以NodeJs的express为例
//设置跨域访问
app.all(‘*‘, function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
next();
});
Nginx实现如下:
server {
...
add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Origin $http_origin;
location /file {
if ($request_method = ‘OPTIONS‘) {
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Methods $http_access_control_request_method;
add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Headers $http_access_control_request_headers;
add_header Access-Control-Max-Age 1728000;
return 204;
}
}
...
}
「window.postMessage()」 方法可以安全地实现跨源通信。可以允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本文档,多窗口,跨域消息传递.多用于窗口间数据通信,这也使它成为跨域通信的一种有效的解决方案.
兼容性:
语法
otherWindow.postMessage(message, targetOrigin, [transfer])
message
你要发送的信息(字符串和对象都可以)targetOrigin
你要发送信息的目标域名transfer
可选参数,与消息一起传输的Transferable
对象序列。这些对象的所有权将提供给目标端,并且它们在发送端不再可用。已经有人写了不错的实践,博主这里就不做介绍,可以阅读postmessage可真太有用了了解。
总结:
postMessage是html5新增的一个解决跨域的方法,主要解决不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递,多用于页面与嵌套的iframe消息传递
由于默认允许跨域,所以导致一些安全问题,主要攻击方式有两种,一是伪造数据发送端,易造成XSS,二是伪造数据获取端,类似JSONP劫持。
用于接收消息的任何事件侦听器必须首先使用origin和可能的source属性检查消息发送者的身份。未能检查origin和可能的source属性可以实现跨站点脚本攻击。
WebSocket 是一种网络通信协议,可在网络浏览器和服务器之间建立“套接字”连接。这种方式本质没有使用了 HTTP 的响应头, 因此也没有跨域的限制。
前端部分(代码来自秋风的笔记-10种跨域解决方案(附终极大招))
<script> let socket = new WebSocket("ws://localhost:8080"); socket.onopen = function() { socket.send("秋风的笔记"); }; socket.onmessage = function(e) { console.log(e.data); };</script>复制代码
后端部分
const WebSocket = require("ws");const server = new WebSocket.Server({ port: 8080 });server.on("connection", function(socket) { socket.on("message", function(data) { socket.send(data); });});
总结:
ws
(如果加密,则为wss
),服务器网址就是 URL。这里需要说明的是: 跨域是浏览器行为,不是服务器行为。同源策略仅是针对浏览器的安全策略。服务器端调用HTTP接口只是使用HTTP协议,不需要同源策略,也就不存在跨域问题。
实际上,请求已经到达服务器了,只不过在回来的时候被浏览器限制了
实现思路:通过Nginx配置一个代理服务器域名与发出请求域名相同,端口不同,反向代理访问目标域名。
背景:domain1需要跨域访问domain2
server {
listen 80;
server_name www.domain1.com;
location / {
proxy_pass www.domain2.com:8080;
}
}
需要说明的是,前端跨域的技术还有许多,只是限于篇幅没有讲到,比如node正向代理,window.name+iframe等。还想了解别的跨域方案的小伙伴可以看本文的参考文章去观摩观摩。
同源策略仅仅是针对浏览器的安全策略,跨域是浏览器行为,如果两个 URL 的 protocol、port (如果有指定的话)和 host 都相同的话,则这两个 URL 是同源。现在有许多的跨域方案可供大家选择,本文仅仅选择了JSONP、CORS、postMessage等6种跨域技术进行了阐述,希望能在梳理自己知识点的同时帮助到一些人。
参考文章:
标签:frame html5 max-age host 防止 details ima 资源 无法
原文地址:https://www.cnblogs.com/rainbowly/p/13251550.html