一、同源和非同源

  1. 含义:

协议相同、域名相同、端口相同

  1. 目的:

保证用户安全信息,防止恶意网站窃取数据

二、利用document.domain降域实现跨域

  1. 原理:

利用的是document.domain降域来实现cookie获取的限制

  1. 新建两个文件夹分别为cookie_origin和cookie_orign_sub,以及建立了两个网站(master.security.com和slave.security.com页面)

  1. 配置虚拟主机(小皮)

  1. 打开D:\phpstudy_pro\Extensions\Apache2.4.39\conf\vhosts选择default-default.conf编辑以下内容

<VirtualHost *:80>DocumentRoot "D:/phpstudy_pro/WWW/cookie_origin"ServerName master.security.comFcgidInitialEnv PHPRC "D:/phpstudy_pro/Extensions/php/php5.6.9nts"AddHandler fcgid-script .phpFcgidWrapper "D:/phpstudy_pro/Extensions/php/php5.6.9nts/php-cgi.exe" .php<Directory  "D:/phpstudy_pro/WWW/cookie_origin">Options FollowSymLinks ExecCGIAllowOverride AllOrder allow,denyAllow from allRequire all grantedDirectoryIndex index.php index.html</Directory>
</VirtualHost><VirtualHost *:80>DocumentRoot "D:/phpstudy_pro/WWW/cookie_origin_sub"ServerName slave.security.comFcgidInitialEnv PHPRC "D:/phpstudy_pro/Extensions/php/php5.6.9nts"AddHandler fcgid-script .phpFcgidWrapper "D:/phpstudy_pro/Extensions/php/php5.6.9nts/php-cgi.exe" .php<Directory  "D:/phpstudy_pro/WWW/cookie_origin_sub">Options FollowSymLinks ExecCGIAllowOverride AllOrder allow,denyAllow from allRequire all grantedDirectoryIndex index.php index.html</Directory>
</VirtualHost>
  1. 打开D:\phpstudy_pro\Extensions\Apache2.4.39\conf的httpd.conf文件,去掉如下注释

LoadModule vhost_alias_module modules/mod_vhost_alias.so
  1. 打开C:\Windows\System32\drivers\etc的host文件,编辑一下内容

127.0.0.1 master.security.com //主页面
127.0.0.1 slave.security.com //子页面
  1. 在建立的cookie_origin文件下新建一个html网页

  1. 访问网站是否成功

  1. 在cookie_origin文件下写入以下内容

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>master</title>
</head>
<body><h1>master</h1><iframe src="http://slave.security.com" id="iFrame"></iframe>
</body>
<script>document.domain = 'security.com';let ifr = document.getElementById('iFrame');ifr.onload = function() {let win = ifr.contentWindow;alert(win.data)}
</script>
</html>

该代码的意思是利用iframe标签来嵌套一个子页面slave.security.com定义的唯一固定id为iFrame,之后利用document.domain给他们降级到同一个域级,这样他们之间就可以实现网页之间的互相访问,设置一个onload函数用来监听,起作用是等iframe访问完成后进行监听子网页,之后利用contentwindow来抓取子页面的内容,最后利用window的data属性弹窗出我们的data数据。

  1. 在cookie_origin_sub下写入以下内容

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>slave</title>
</head>
<body><h1>slave</h1>
</body>
<script>document.domain = 'security.com';window.data = 'data:111';
</script>
</html>
  1. 最后检验我们的结果

三、利用location.hash配合iframe实现跨域(不推荐)

  1. 原理

#data就是location.hash,改变hash值不会导致页面刷新,所以可以利用hash值来进行数据的传递,所以我们利用ifrom这个标签来实现数据传输,子页面收到父页面的请求后修改父页面的hash值,但是由于两个页面不在同一个域下,所以浏览器不允许修改,需要子页面进行iframe请求父页面的同源页面c.html页面,之后将改变的hash值给我们的c.html,我们的c.html请求两次父页面就实现了跨域。

  1. 虚拟主机配置和上一个实验是一样的(主网页www.aaa.com子网页www.bbb.com)

  1. 在cross_origin编写以下内容

!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>aaaaaaaaaa</title>
</head><body><div>aaaaaaaaaaaaa</div>
</body>
<script>var ifr = document.createElement('iframe');ifr.src = 'http://www.bbb.com#data';ifr.style.display = 'none';document.body.appendChild(ifr);//请求跨域的操作function checkHash() {try {let data = location.hash ? location.hash.substring(1) : ' ';console.log('获得到的数据是:', data);} catch (e) {}}checkHash();window.addEventListener('hashchange', function (e) {console.log('获得的数据是:', location.hash.substring(1));});
</script></html>

该代码的意思是15-16行表示的是一个跨域的一个请求操作,之后进行一个哈希函数的的监听作用(checkhash),如果哈希值发生改变则会通过js.substring(1)从改变的第一个值进行截取,之后打印出改变的值,

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>cccccccccccc</title>
</head>
<body></body>
<script>parent.parent.location.hash = self.location.hash.substring(1)
</script>
</html>
  1. 在cross_origin_sub编写一下内容

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>bbbbb</title>
</head><body><div>bbbbbbbbbbbb</div>
</body>
<script>switch (location.hash) {case "#data":callback();break;}function callback() {const data = "some number: 1111"// parent.location.hash = data;try {parent.location.hash = data;} catch (e) {// ie, chrome 下的安全机制无法修改 parent.location.hash// 所以要利用一个中间的代理 iframe var ifrproxy = document.createElement('iframe');ifrproxy.style.display = 'none';ifrproxy.src = 'http://www.aaa.com/c.html#' + data;     // 该文件在请求域名的域下document.body.appendChild(ifrproxy);}}
</script>
</html>

子页面的意思是当收到父页面的一个请求后,通过switch函数来判断是不是”#data“如果是就调用callback函数,我们利用parent.location.hash = data;把callback函数把父页面的哈希值变成了some number: 1111,之后父页面监听后,便将我们改变的值传递给父页面,之后父页面会打印出来,结果我们发现不行,原因是由于浏览器的安全机制我们无法修改父页面的哈希值,所以产生了我们的第三方代理页面(c.html)其要求是必须和父页面同源。我们的办法是增加一个catch函数,当我们的try函数判断受到了浏览器安全机制的限制时候我们进入到catch函数中,在这个函数中我们重新请求了一个iframe页面嵌套请求,请求我们的c.html,因为我们是在c.html里面进行请求的,相当于我们在父页面的子页面里面又嵌套了一个子页面,所以我们需要传输两次到我们的父页面。那么这个c.html相当于一个中转站,将我们的somenumber传两次传回到我们的父页面。

  1. 整体的过程

父页面aaa.com先进行请求子页面bbb.com,请求完成后,利用checkhash监听子页面的的哈希值有木有发生变化,子页面在接收到父页面的请求后判断是否有#data这个哈希值,入过有就会将其的data改为some number:1111,这时候返回给父页面,由于父页面有安全机制,就会显示不是同源,这时候返回给我们的子页面,之后子页面就会在去请求父页面同源下的一个c.html页面,我们利用c.html来将我们bbb.com页面修改的哈希值返回两次parent给我们的父页面,之后我们父页面识别是同源下的页面请求,并且监听到哈希值发生改变就打印出我们的内容

  1. 结果

  1. 缺点

(1)数据直接暴露在了url中

(2)数据容量和类型都有限

四、利用windows.name进行跨域

1.原理和location.hash一样,只是父页面指向子页面,子页面a又指向子页面b,利用的子页面a做的跳

转而已。

2.父页面的代码

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>window_name</title>
</head><body><script>let data = '';const ifr = document.createElement('iframe');ifr.src = "http://www.aaa.com";ifr.style.display = 'none';document.body.appendChild(ifr);ifr.onload = function () {ifr.onload = function () {data = ifr.contentWindow.name;console.log('收到数据:', data);}ifr.src = "http://www.security.com/c.html";}</script>
</body></html>

我们可以在该页面下新建一个iframe,该iframe的src属性指向服务器地址(利用iframe标签的跨域能力),服务器文件b.html设置好window.name值。但是由于a.html页面和该页面iframe的src不同源的话,则无法操作iframe里的任何东西,所以就取不到iframe的name值,所以我们需要在b.html加载完之后重新换个src区指向一个同源的html文件,或者设置成about:blank都行,这时候我们只要在a.html相同的目录下件一个c.html空白即可。如果不重新指向src的话直接获取的window.name的话就会报错。

3. c.html

window.name = "hello";

五、postMessage跨域(重点推荐)

  1. 原理

www.security.com到www.aaa.com实现跨域操作,官方使用window.postmessage,其原理就是从源区域跨域的时候,通过postmessage的方法属性,对发送的页面进行监听,跨域的页面也进行postmessage属性的一个监听,从而来实现跨域的操作

  1. 在postmessage.html页面

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>postMessage</title>
</head><body><iframe src="http://www.aaa.com"></iframe><script>window.onload = function () {let targetOrigin = 'http://www.aaa.com';//想要操作当前iframe的时候,就像该ifranme中postMessage()一个东西。window.frames[0].postMessage('我要给你发消息了!', targetOrigin);//*表示任何域都可以监听。}//当我监听到message事件的时候,我就知道有人向我发送数据了,我获得了数据就可以做对应的事情。内部对消息做实现window.addEventListener('message', function (e) {console.log('security.com接收到的消息:', e.data);});</script>
</body></html>

首先security页面向aaa页面发送页面的请求,之后通过postmessage对该网页发送一些消息,于此同时我们也可以通过

  1. 在aaa.com页面创建一个页面用来监听来自security页面的消息

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>postmessag</title>
</head><body><div>aaaaaaaaaa</div><script>window.addEventListener('message', function (e) {if (e.source != window.parent) {return;}let data = e.data;console.log('aaa.com接收到的消息:', data);parent.postMessage('我已经接收到消息了!', e.origin);})</script>
</body></html>

该页面利用window.addeventlistener来监听来自sercurity的消息,主要靠的是监听message这个属性,如果不是来自security的消息就拒绝掉,如果是的话会通过event.data来获取这个消息的内容,并且告诉父元素其已经接收到该消息。

4.结果

六、postmessage的localstorage存储数据

  1. 原理:

通过postmessage方法进行对别的页面进行localstore的读写存储

  1. 在www.security.com页面建立一个对其他页面的存储请求

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>localstorage</title>
</head><body><iframe src="http://www.aaa.com"></iframe><script>window.onload = function () {let targetOrigin = 'http://www.aaa.com';//想要操作当前iframe的时候,就像该ifranme中postMessage()一个东西。// var win = document.getElementsByTagName('iframe')[0].contentWindow; var obj = { name: 'oupeng','age': 10 };window.frames[0].postMessage(JSON.stringify({ key: 'storage', data: obj }), targetOrigin);//*表示任何域都可以监听。}//当我监听到message事件的时候,我就知道有人向我发送数据了,我获得了数据就可以做对应的事情。内部对消息做实现window.addEventListener('message', function (e) {console.log('security.com接收到的消息:', e.data);});</script>
</body></html>

通过iframe对www.aaa.com页面进行一个请求,之后对该窗口进行一个获取window的属性,建立一个obj的对象,在这个对象里加入我们需要存储的内容,之后通过json.stringify属性将这个数据转换为json对象,在通过postmessage方法将其传递到www.aaa.com页面

3.在ww.aaa.com页面

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>localstorage</title>
</head><body><script>window.addEventListener('message',receiveMessage);function receiveMessage(event) {if (event.origin !== 'http://www.security.com') {return;}var payload = JSON.parse(event.data);localStorage.setItem(payload.key, JSON.stringify(payload.data));};</script>
</body></html>

在www.aaa.com页面,通过监听window.message的属性从而来获取到来自www.security.com传递过来的数据,将其转换为字符串,然后通过localstorage.setitem将获取的obj方法存储到localstorage中。

4.结果

七、JSONP(极力不推荐,淘汰)

  1. 原理

通过建立一个<script>的请求,其不受跨源的要求,建立一个网页的请求,在建立的网页请求网址后面添加一个callback=foo的参数,并且通过拼接字符拿到foo这个函数中的内容。

2.在www.security.com建立一个请求拼接json的函数

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>jsonp</title>
</head><body><script>function addScriptTag(src) {var script = document.createElement('script');script.setAttribute('type', 'text/javascript');script.src = src;document.body.appendChild(script);}window.onload = function () {addScriptTag('http://www.aaa.com/index.html?callback=foo');}function foo(data) {console.log('Your public IP address is: ' + data.ip);};</script>
</body></html>

该代码的意思是建立一个函数进行<script>的标签请求,在请求的网址后面加入callback=foo这个参数,并且在后面拼接出得出服务器请求的json数据

3.在www.aaa.com中创建一个json数据库

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><div>aaaaaaaaaa</div><script>function foo(data){console.info(data);}var obj = {'ip': '8.8.8.8'};foo(obj);</script>
</body>
</html>

其是指建立一个foo的json数据库,里面存放着我们需要请求的数据内容。

4.结果

八、WebSocket

  1. 原理

WebSocket 是一种通信协议,使用ws://(非加密)和wss://(加密)作为协议前缀。该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信。

  1. 在本地建立socket.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>nodesjs</title>
</head>
<body><script>let socket = new WebSocket('ws://127.0.0.1:3000');socket.onopen = function () {socket.send('l love  you');}socket.onmessage = function (e) {console.log(e.data);}</script>
</body>
</html>

该意思是利用websocket先进行ws的对websocket库进行一个请求,在通过socket.send方法对该库发送一条消息,之后在通过socket.onmessage方法对其进行一个数据的监听,从而获取数据。

3.建立socket.js库的相关配置

let express = require('express');
let app = express();
let WebSocket = require('ws');
let wss = new WebSocket.Server({port:3000});
wss.on('connection',function(ws){ws.on('message',function (data) {console.log(data);ws.send('i hate you')});
})

该库的意思是建立一个连接ws的3000端口请求,收到该请求后利用message来获取得到的数据,之后传递给请求页面一个l hate you的消息。

  1. 先在本地下载websocket服务器,之后node socket.js,最后访问www.security.com页

  1. 结果

九、CORS(待补充,自己太菜了,弄不出来)

CORS 是一个 W3C 标准,全称是“跨域资源共享”(Cross-origin resource sharing)。它允许浏览器向跨域的服务器,发出XMLHttpRequest请求,从而克服了 AJAX 只能同源使用的限制。

安全基础第五天:跨域相关推荐

  1. iframe跨域调用js_郑州Web前端基础学习之JS跨域知识梳理

    JS是Web前端开发三要素之一,是郑州Web前端基础学习中非常重要的知识点.JS涉及的知识点多且杂,很多同学反映不知如何下手,事实上,只要你认真记.多练习,就可以慢慢掌握它.今天千锋郑州Web前端培训 ...

  2. .NET6之MiniAPI(十五):跨域CORS(下)

    前一篇的跨域请求的方式是松宽的方式,毕竟跨域有安全风险,应尽量少的允许访问必要资源,本篇分别从请求方法,请求头和请求凭据方面了解跨域设置. 请求方法: api项目,get,post是默认访问,这里只设 ...

  3. 浏览器基础(2)-跨域

    跨域 跨域是啥? 下面是一个例子来理解同源策略 为什么会有同源策略? 解决跨域的常见方式 JSONP CORS(Cross-origin resource sharing)跨域资源共享 什么情况下需要 ...

  4. 前端系列三十五:跨域问题及解决方案

    SwitchHosts下载及添加配置: http://test.auclt.baidu.os.com http://test.asclt.baidu.os.com 这里仔细观察会发现请求地址后缀名后三 ...

  5. 【Vue基础】什么是跨域?如何解决跨域问题?浅浅了解一下什么是登录鉴权

    1. 什么是跨域? 在了解什么是跨域之前,我们首先要了解一个概念--同源策略. 同源策略: 同源策略/SOP(Same Origin Policy) 是一种约定,由 Netscape 公司 1995 ...

  6. AJAX请求和跨域请求详解(原生JS、Jquery)

    一.概述 AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术. AJAX = 异步 JavaScript 和 XML,是一种用于创建快速动态网页的技术.通过在后台与服务器进行少量数 ...

  7. [跨域]前端解决跨域问题

    1.同源策略如下: URL 说明 是否允许通信 http://www.a.com/a.js http://www.a.com/b.js 同一域名下 允许 http://www.a.com/lab/a. ...

  8. 什么是跨域?什么情况下会发生跨域请求?

    跨域,指的是浏览器不能执行其他网站的脚本.它是由浏览器的同源策略造成的,是浏览器施加的安全限制. 同源策略:所谓同源是指:协议,域名,端口均相同.即便两个不同的域名指向同一个ip地址,也非同源. ht ...

  9. document.domain 跨域问题[转]

    document.domain用来得到当前网页的域名. 比如打开百度,在地址栏里输入: javascript:alert(document.domain); //www.baidu.com 弹出窗体: ...

  10. SharePoint 2013 APP 开发示例 (六)服务端跨域访问 Web Service (REST API)

    上个示例(SharePoint 2013 APP 开发示例 (五)跨域访问 Web Service (REST API))是基于JavaScript,运行在web browser内去访问REST AP ...

最新文章

  1. ceph bluestore源码分析:非对齐写逻辑
  2. pycharm 常用代码签名
  3. 玲珑杯 1157 - 造物主的戒律 主席树+离散化
  4. mysql中char和text的区别_mysql中text与varchar与char的区别
  5. 笔记-知识产权与标准化知识-软件质量模型(重)
  6. Nuxt.js项目不识别import原因及解决方法
  7. php 导航栏链接网页,怎样用php来给网页做导航栏_php实例
  8. Linux下的web调度器——squid实现(负载均衡)
  9. 循环赛日程安排(构造、分治)
  10. 阶段1 语言基础+高级_1-2 -面向对象和封装_1面向对象思想的概述
  11. ES6 Number
  12. Web入门之VScode连接数据库sql server(超详细)
  13. surf算法matlab代码,surf算法matlab源码
  14. 卸载WPS后如何修复Office文档图标显示异常
  15. java随机生成三位数
  16. Jointly Embedding Knowledge Graphs and Logical Rules
  17. 2021届Java开发求职-------面试实战之Vivo提前批
  18. Word 设置标题编号
  19. 【CentOS】CentOS7最小安装版 VMware Tools安装
  20. matlab实现图形几何变换如平移,matlab实现平面图形的几何变换

热门文章

  1. Perl基本数组排序方法介绍
  2. CSDN编程竞赛第六期
  3. 大数据pyspark之计算用户每个页面停留时间
  4. 一文解答什么是集成灶,有什么优缺点
  5. 51单片机入门 7.11(始)
  6. 互融云汽车金融系统开发 “互联网+汽车金融”业务平台开发 助力打造立体化管理平台
  7. Struts 中的ActionForm
  8. python方括号里面单引号_Python中单引号,双引号,三个单引号,外双单引号内双引号,外双引号内单引号的区别...
  9. 压敏电阻烧坏的原因后果及解决办法
  10. 趣图:这真是 Feature,不是 Bug