浏览器同源策略,及跨域解决方案

本文涉及的产品
.cn 域名,1个 12个月
简介: 一、Origin(源)源由下面三个部分组成:域名端口协议两个 URL ,只有这三个都相同的情况下,才可以称为同源。下来就以这个链接来比较说明:对比URL结果原因http://m.

一、Origin(源)

源由下面三个部分组成:

  1. 域名
  2. 端口
  3. 协议

两个 URL ,只有这三个都相同的情况下,才可以称为同源。

对比URL 结果 原因
http://m.example.com/page.html 不同源 域名不同
不同源 协议不同
http://www.example.com:8080/page.html 不同源 端口不同
同源 同域名,同端口,同协议


二、同源策略

浏览器的同源策略是一种安全功能,同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。所以a.com下的js脚本采用ajax读取b.com里面的文件数据是会报错的。


三、哪些会受到同源策略限制

对于浏览器来说,除了DOM、Cookie、XMLHttpRequest 会受到同源策略的限制外,浏览器加载的一些第三方插件也有各自的同源策略。最常见的一些插件如 Flash ,有自己的控制策略。

所以,想要体验下,同源策略限制,你就可以写一个ajax 请求,比如127.0.0.1:80 要请求127.0.0.1:8080 的 a.js ;
这里写图片描述
127.0.0.1:80 里的index.html


另一个页面

然后就会报错了,出现了同源策略限制了。

四、什么是跨域呢

说的跨域,其实呢就是跨源。而跨域是一个统称,通过上面的我们知道了,因为同源策略,不同源之间,不能进行交互。那么跨域就是解决不同源之间发起请求、请求数据、发送数据、通信等交互问题解决方法的统称。

在浏览器中,

127.0.0.1:8080 index.js

function say(){
    var app = document.getElementById('app');
    app.innerHTML = "我是被挂载到window对象上的方法,所以可以获取到我!";
}


五、jsonp跨域

到底什么是jsonp 跨域呢?其实,jsonp 跟 json 两者没有什么关系,也没有什么相似的地方,大家都知道json 是一种数据格式,而jsonp 之所以被称为jsonp,我认为跟它发出请求后,一般得到的,都是json格式数据有关吧。

上面说过了,

function say(){
    console.log("666");
}
say();

当打开127.0.0.1/index.html页面时,

然后是 127.0.0.1:8080 index.php文件:

 'zdx',
                'sex' => 'man',
                'age' => 18

             );
$callback = $_GET['callback'];
echo $callback . '(' . json_encode($data) . ')';
?>

当访问jsonp.html时,其中的

而IE8 - IE9是通过XDR对象实现 CORS 的。
基于XDR的 index.html 代码如下:


XDR对象实现CORS

注意:CORS可以发起 GET、POST请求,但是发送的请求,默认不会随带 cookie 一起发送, 也不会接受后端发过来的 cookie;

要想随带cookie 一起发送。
需要在127.0.0.1:8080 index.php添加 header('Access-Control-Allow-Credentials:true');头部,然后在127.0.0.1:80 index.htmlvar xhr = new XMLHttpRequest();后面添加xhr.withCredentials = true;


七、document.domain 降域

同源策略认为域和子域属于不同的域,如:
child1.a.com 与 a.com,
child1.a.com 与 child2.a.com,
xxx.child1.a.com 与 child1.a.com
两两不同源,可以通过设置 document.domain='a.com',浏览器就会认为它们都是同一个源。想要实现以上任意两个页面之间的通信,两个页面必须都设置documen.damain='a.com'。

此方式的特点:

  1. 只能在父域名与子域名之间使用,且将 xxx.child1.a.com域名设置为a.com后,不能再设置成child1.a.com。
  2. 存在安全性问题,当一个站点被攻击后,另一个站点会引起安全漏洞。
  3. 这种方法只适用于 Cookie 和 iframe 窗口。

下面来模拟一下,在a.com 与 child1.a.com 之间通信。如果要在本机测试,请自行更改host 等,访问的都是本机80端口,这里就不在累述了。
a.com index.html


主页面

child1.a.com index.php

child1.a.com index1.html


child

注意:此方法可以发起 GET、POST 请求,发起的请求不会随带 cookie 一起发送,也不能接受后端发过来的 cookie

八、HTML5的postMessage方法

这是html5 新加的方法。
这个方法允许一个页面的脚本发送数据到另一个页面的脚本中,不管脚本是否跨域。在一个window对象上调用postMessage()会异步的触发window上的onmessage事件,然后触发定义好的事件处理方法。一个页面上的脚本仍然不能直接访问另外一个页面上的方法或者变量,但是他们可以安全的通过消息传递技术交流。

比如说父页面为127.0.0.1:80 的页面,传送数据给 127.0.0.1:8080 的子页面:
127.0.0.1:80 index.html


父页面

127.0.0.1:8080 index.html

 

子页面

然后访问:127.0.0.1:80/index.html,就得到想要的结果了,这方法通常用来进行两个窗口通信。


九、HTML5的WebSocket

现代浏览器允许脚本直连一个WebSocket地址而不管同源策略。然而,使用WebSocket URI的时候,在请求中插入Origin头就可以标识脚本请求的源。为了确保跨站安全,WebSocket服务器必须根据允许接受请求的白名单中的源列表比较头数据。

这个因为需要后端的支持,而且比较复杂,这里就不举例子了,感兴趣的可以去查阅资料。

这里贴一个阮老师的websocket教程吧:WebSocket 教程


十、window.name

window对象有一个name属性,该属性有一个特征:即在一个窗口的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每一个页面对window.name都有读写的权限,window.name是持久的存在于一个窗口载入的所有页面中的,并不会因为新的页面的载入而被重置。

因此,就可以利用此特性,进行跨域通信。
127.0.0.1:80 index.html

 

window.name

127.0.0.1:8080 index.html

 

这时,访问127.0.0.1:80/index.html,跳转到的127.0.0.1:8080/index.html就能接受传过来的数据了。

十一、location.hash

原理是利用location.hash来进行传值。在url: http://a.com#helloword中的‘#helloworld’就是location.hash
127.0.0.1:80 index.html

 

window.name

127.0.0.1:8080 index.html

 

这时,访问127.0.0.1:80/index.html,跳转到的127.0.0.1:8080/index.html就能接受传过来的数据了。

十二、proxy 跨域

这个完全是后端的实现,我就不说了,我也搞不懂,也没意义。哈哈。

这里说的还是皮毛,这些跨域方案只是工具,怎么利用,就看你了。

相关文章
|
8月前
|
移动开发 小程序 API
微信外部浏览器或短信链接唤起微信小程序的解决方案
微信外部浏览器或短信链接唤起微信小程序的解决方案
1730 1
|
2月前
|
移动开发 JSON JavaScript
|
2月前
|
存储 安全 JavaScript
浏览器的同源策略
【10月更文挑战第31天】浏览器的同源策略是浏览器安全模型的重要组成部分,它通过限制不同源之间的资源交互,有效地保护了用户和网站的安全。开发者在进行Web开发时,需要充分理解和遵循同源策略,同时合理地运用各种跨域技术来满足业务需求,确保网站的安全性和功能性的平衡。
65 2
|
3月前
|
Web App开发 JSON 安全
Chrome浏览器的跨域问题
【10月更文挑战第6天】
|
4月前
|
Web App开发 存储 前端开发
Chrome浏览器的跨域问题
Chrome浏览器的跨域问题
|
5月前
|
数据采集 Web App开发 测试技术
使用Selenium调试Edge浏览器的常见问题与解决方案
在互联网数据采集领域,Selenium常用于自动化网页爬取。针对使用Edge浏览器时遇到的启动远程调试失败、访问受限及代理IP设置等问题,本文提供了解决方案。通过特定命令启动Edge的远程调试模式,并利用Python脚本配合Selenium库,可实现代理IP、User-Agent的设定及Cookie管理等高级功能,有效提升爬虫稳定性和隐蔽性。遵循步骤配置后,即可顺畅执行自动化测试任务。
1183 1
使用Selenium调试Edge浏览器的常见问题与解决方案
|
5月前
|
Web App开发 JSON 数据格式
【Azure Developer】浏览器查看本地数据文件时遇见跨域问题(CORS)
【Azure Developer】浏览器查看本地数据文件时遇见跨域问题(CORS)
【Azure Developer】浏览器查看本地数据文件时遇见跨域问题(CORS)
|
5月前
|
Web App开发 JSON 安全
【跨域难题终结者】:一键解锁Chrome浏览器神秘设置,彻底告别开发阶段的跨域烦恼!
【8月更文挑战第20天】跨域是前端开发常遇难题,尤其在前后端分离项目中。浏览器因安全考量会阻止不同源间的请求。本文对比CORS、JSONP、代理服务器等解法,并介绍开发阶段通过调整Chrome设置来临时禁用跨域限制的方法,提供启动Chrome及使用`fetch`API示例,适合快速测试。但请注意这不适用于生产环境,存在一定安全风险。
1383 1
|
6月前
|
移动开发 JSON JavaScript
浏览器跨域
浏览器跨域
|
7月前
|
Web App开发 JSON 数据格式
【Azure Developer】浏览器查看本地数据文件时遇见跨域问题(CORS)
Access to XMLHttpRequest at 'file:///C:/Users/.../failedrequests.json' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, isolated-app, chrome-extension, chrome-untrusted, https, edge. reportdata/failedrequests.json:1 Fail