当前位置: 首页 > 编程日记 > 正文

前端解决跨域问题的8种方案(最新最全)

.同源策略如下:

URL说明是否允许通信
http://www.a.com/a.js
http://www.a.com/b.js
同一域名下允许
http://www.a.com/lab/a.js
http://www.a.com/script/b.js
同一域名下不同文件夹允许
http://www.a.com:8000/a.js
http://www.a.com/b.js
同一域名,不同端口不允许
http://www.a.com/a.js
https://www.a.com/b.js
同一域名,不同协议不允许
http://www.a.com/a.js
http://70.32.92.74/b.js
域名和域名对应ip不允许
http://www.a.com/a.js
http://script.a.com/b.js
主域相同,子域不同不允许
http://www.a.com/a.js
http://a.com/b.js
同一域名,不同二级域名(同上)不允许(cookie这种情况下也不允许访问)
http://www.cnblogs.com/a.js
http://www.a.com/b.js
不同域名不允许
特别注意两点:第一,如果是协议和端口造成的跨域问题“前台”是无能为力的,第二:在跨域问题上,域仅仅是通过“URL的首部”来识别而不会去尝试判断相同的ip地址对应着两个域或两个域是否在同一个ip上。“URL的首部”指window.location.protocol +window.location.host,也可以理解为“Domains, protocols and ports must match”。

2. 前端解决跨域问题

1> document.domain + iframe      (只有在主域相同的时候才能使用该方法)

1) 在www.a.com/a.html中:

复制代码
document.domain = 'a.com';
var ifr = document.createElement('iframe');
ifr.src = 'http://www.script.a.com/b.html';
ifr.display = none;
document.body.appendChild(ifr);
ifr.onload = function(){var doc = ifr.contentDocument || ifr.contentWindow.document;//在这里操作doc,也就是b.htmlifr.onload = null;
};
复制代码

2) 在www.script.a.com/b.html中:

document.domain = 'a.com';

2> 动态创建script

这个没什么好说的,因为script标签不受同源策略的限制。

复制代码
function loadScript(url, func) {var head = document.head || document.getElementByTagName('head')[0];var script = document.createElement('script');script.src = url;script.onload = script.onreadystatechange = function(){if(!this.readyState || this.readyState=='loaded' || this.readyState=='complete'){func();script.onload = script.onreadystatechange = null;}};head.insertBefore(script, 0);
}
window.baidu = {sug: function(data){console.log(data);}
}
loadScript('http://suggestion.baidu.com/su?wd=w',function(){console.log('loaded')});
//我们请求的内容在哪里?
//我们可以在chorme调试面板的source中看到script引入的内容
复制代码

3> location.hash + iframe

原理是利用location.hash来进行传值。

假设域名a.com下的文件cs1.html要和cnblogs.com域名下的cs2.html传递信息。
1) cs1.html首先创建自动创建一个隐藏的iframe,iframe的src指向cnblogs.com域名下的cs2.html页面
2) cs2.html响应请求后再将通过修改cs1.html的hash值来传递数据
3) 同时在cs1.html上加一个定时器,隔一段时间来判断location.hash的值有没有变化,一旦有变化则获取获取hash值
注:由于两个页面不在同一个域下IE、Chrome不允许修改parent.location.hash的值,所以要借助于a.com域名下的一个代理iframe

代码如下:
先是a.com下的文件cs1.html文件:

复制代码
function startRequest(){var ifr = document.createElement('iframe');ifr.style.display = 'none';ifr.src = 'http://www.cnblogs.com/lab/cscript/cs2.html#paramdo';document.body.appendChild(ifr);
}function checkHash() {try {var data = location.hash ? location.hash.substring(1) : '';if (console.log) {console.log('Now the data is '+data);}} catch(e) {};
}
setInterval(checkHash, 2000);
复制代码

cnblogs.com域名下的cs2.html:

复制代码
//模拟一个简单的参数处理操作
switch(location.hash){case '#paramdo':callBack();break;case '#paramset'://do something……break;
}function callBack(){try {parent.location.hash = 'somedata';} catch (e) {// ie、chrome的安全机制无法修改parent.location.hash,// 所以要利用一个中间的cnblogs域下的代理iframevar ifrproxy = document.createElement('iframe');ifrproxy.style.display = 'none';ifrproxy.src = 'http://a.com/test/cscript/cs3.html#somedata';    // 注意该文件在"a.com"域下document.body.appendChild(ifrproxy);}
}
复制代码

a.com下的域名cs3.html

//因为parent.parent和自身属于同一个域,所以可以改变其location.hash的值
parent.parent.location.hash = self.location.hash.substring(1);

4> window.name + iframe

window.name 的美妙之处:name 值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的 name 值(2MB)。

1) 创建a.com/cs1.html

2) 创建a.com/proxy.html,并加入如下代码

复制代码
<head><script>function proxy(url, func){var isFirst = true,ifr = document.createElement('iframe'),loadFunc = function(){if(isFirst){ifr.contentWindow.location = 'http://a.com/cs1.html';isFirst = false;}else{func(ifr.contentWindow.name);ifr.contentWindow.close();document.body.removeChild(ifr);ifr.src = '';ifr = null;}};ifr.src = url;ifr.style.display = 'none';if(ifr.attachEvent) ifr.attachEvent('onload', loadFunc);else ifr.onload = loadFunc;document.body.appendChild(iframe);}
</script>
</head>
<body><script>proxy('http://www.baidu.com/', function(data){console.log(data);});</script>
</body>
复制代码

3 在b.com/cs1.html中包含:

<script>window.name = '要传送的内容';
</script>

 

5> postMessage(HTML5中的XMLHttpRequest Level 2中的API)

1) a.com/index.html中的代码:

复制代码
<iframe id="ifr" src="b.com/index.html"></iframe>
<script type="text/javascript">
window.onload = function() {var ifr = document.getElementById('ifr');var targetOrigin = 'http://b.com';  // 若写成'http://b.com/c/proxy.html'效果一样// 若写成'http://c.com'就不会执行postMessage了ifr.contentWindow.postMessage('I was there!', targetOrigin);
};
</script>
复制代码

2) b.com/index.html中的代码:

复制代码
<script type="text/javascript">window.addEventListener('message', function(event){// 通过origin属性判断消息来源地址if (event.origin == 'http://a.com') {alert(event.data);    // 弹出"I was there!"alert(event.source);  // 对a.com、index.html中window对象的引用// 但由于同源策略,这里event.source不可以访问window对象}}, false);
</script>
复制代码

6> CORS

CORS背后的思想,就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功,还是应该失败。

IE中对CORS的实现是xdr

复制代码
var xdr = new XDomainRequest();
xdr.onload = function(){console.log(xdr.responseText);
}
xdr.open('get', 'http://www.baidu.com');
......
xdr.send(null);
复制代码

其它浏览器中的实现就在xhr中

复制代码
var xhr =  new XMLHttpRequest();
xhr.onreadystatechange = function () {if(xhr.readyState == 4){if(xhr.status >= 200 && xhr.status < 304 || xhr.status == 304){console.log(xhr.responseText);}}
}
xhr.open('get', 'http://www.baidu.com');
......
xhr.send(null);
复制代码

实现跨浏览器的CORS

复制代码
function createCORS(method, url){var xhr = new XMLHttpRequest();if('withCredentials' in xhr){xhr.open(method, url, true);}else if(typeof XDomainRequest != 'undefined'){var xhr = new XDomainRequest();xhr.open(method, url);}else{xhr = null;}return xhr;
}
var request = createCORS('get', 'http://www.baidu.com');
if(request){request.onload = function(){......};request.send();
}
复制代码

7> JSONP

JSONP包含两部分:回调函数和数据。

回调函数是当响应到来时要放在当前页面被调用的函数。

数据就是传入回调函数中的json数据,也就是回调函数的参数了。

复制代码
function handleResponse(response){console.log('The responsed data is: '+response.data);
}
var script = document.createElement('script');
script.src = 'http://www.baidu.com/json/?callback=handleResponse';
document.body.insertBefore(script, document.body.firstChild);
/*handleResonse({"data": "zhe"})*/
//原理如下:
//当我们通过script标签请求时
//后台就会根据相应的参数(json,handleResponse)
//来生成相应的json数据(handleResponse({"data": "zhe"}))
//最后这个返回的json数据(代码)就会被放在当前js文件中被执行
//至此跨域通信完成
复制代码

jsonp虽然很简单,但是有如下缺点:

1)安全问题(请求代码中可能存在安全隐患)

2)要确定jsonp请求是否失败并不容易

8> web sockets

web sockets是一种浏览器的API,它的目标是在一个单独的持久连接上提供全双工、双向通信。(同源策略对web sockets不适用)

web sockets原理:在JS创建了web socket之后,会有一个HTTP请求发送到浏览器以发起连接。取得服务器响应后,建立的连接会使用HTTP升级从HTTP协议交换为web sockt协议。

只有在支持web socket协议的服务器上才能正常工作。

var socket = new WebSockt('ws://www.baidu.com');//http->ws; https->wss
socket.send('hello WebSockt');
socket.onmessage = function(event){var data = event.data;
}

转载于:https://www.cnblogs.com/qiushuixizhao/p/5161101.html

相关文章:

IDEA中修改文件的默认创建方式

今天很手欠地在创建application-dev.yml文件的时候将application-dev这个名字的文件成功变成了一个我不认识的文件打开方式了&#xff0c;如下图&#xff1a; 可以看到&#xff0c;这个application-dev.yml文件从原来的SpringBoot的配置文件变成一个我们不认识的文件格式… 补…

ArcEngine 直连连接SDE

关键代码IPropertySet pPropertySet new PropertySetClass();pPropertySet.SetProperty("SERVER", sde.IpAdress);pPropertySet.SetProperty("INSTANCE", "sde:oracle11g$//" sde.IpAdress "/" sde.Instance); pPrope…

Dubbo和Spring Cloud微服务架构对比

一、为什么要使用微服务&#xff1f; 微服务提倡将单一应用程序划分成一组小的服务&#xff0c;服务之间互相协调、互相配合。 今天我们来了解下业内主要的微服务框架&#xff1a;Dubbo 和 Spring Cloud 微服务主要的优势 降低复杂度将原来耦合在一起的复杂业务拆分为单个服务,…

Unity 3D为策略游戏创建地图学习教程

MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44.1 KHz&#xff0c;2 Ch 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; |时长:30节课(7h 42m) |大小:5 GB 含项目文件 沿着曲线、高程图和数据结构移动对象 你会学到: Unity&…

Lambda表达式(简单解析)

Lambda表达式 Lambda表达式其实是JDK8的一个新特性。所谓Lambda表达式指的是应用在单一抽象方法接口环境下的一种简化定义形式&#xff0c;可以用于解决匿名内部类中定义复杂的问题。 我们先来看一段代码&#xff0c;如下&#xff1a; interface Customer{public void print(…

YTU 2899: D-险恶逃生 I

2899: D-险恶逃生 I 时间限制: 1 Sec 内存限制: 128 MB提交: 130 解决: 55题目描述 Koha被邪恶的巫师困在一个m*n的矩阵当中&#xff0c;他被放在了矩阵的最左上角坐标(0,0)处&#xff0c;而唯一的出口在矩阵最右下角坐标(m-1,n-1)处&#xff0c;他每次只能向右或者向下移动一…

2021-2027年中国托育服务行业市场研究及前瞻分析报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新&#xff08;交付时间约3个工作日&#xff09; 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国托育服务行业市场行业相关概述、中国托育服务行业市场行业运行环境、分析了中国托育服务行…

2021全国高校计算机能力挑战赛(初赛)Java试题一

从大于等于N 的正整数里找到一个最小的数M,使之满足:M和M的逆序数(如1230的逆序数为321)的和为一个[100000,200000]区间内的值。 import java.util.Scanner; public class Main {public static void main(String[] args){Scanner scanner new Scanner(System.in);int N scann…

Blender写实产品创作学习教程

Blender中的现实产品创作 Realistic Product Creation in Blender MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44.1 KHz&#xff0c;2 Ch 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09;|时长:71节课(6小时30分钟)|大小解压…

试题 入门训练 Fibonacci数列(Java)

题目&#xff1a; 一开始我看到这题目其实觉得挺简单的&#xff0c;第一次简单写了一个循环就提交上去了&#xff0c;结果… 我意识到这是因为超过long类型的最大范围导致的&#xff0c;所以第二次换成BigInteger大整数类型&#xff0c;但最后一个测试点超时了… 通过百度…

翻译BonoboService官网的安装教程

This page covers simple Bonobo Git Server installation. Be sure to check prerequisites page before installation and for other sections visit the documentation page. 此页包括简单的Bonobo Git 服务安装。在安装和查看文档页之前要先查看系统要求页。 The following…

2021-2027年中国涂装行业市场需求预测与投资战略规划分析报告

【报告类型】产业研究 【报告价格】4500起 【出版时间】即时更新&#xff08;交付时间约3个工作日&#xff09; 【发布机构】智研瞻产业研究院 【报告格式】PDF版 本报告介绍了中国涂装行业市场行业相关概述、中国涂装行业市场行业运行环境、分析了中国涂装行业市场行业的…

【SICP练习】84 练习2.56

这道题的代码略长啊。不过我也是因此而知道Edwin上的代码居然可以复制到word上&#xff0c;以前还想当然的以为不能复制的&#xff0c;毕竟在Edwin上粘贴用的CtrlY&#xff0c;而不是CtrlV。在这里我就只将书上没有的代码贴出来了。 (define (deriv exp var)(cond ((number? e…

2021全国高校计算机能力挑战赛(初赛)Java试题二

某地大数据防疫平台记录了往来的所有防疫相关信息&#xff0c;包括本地或外地人员、健康码颜色、接种疫苗情况、最近一次核酸结果等 import java.util.ArrayList; import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner new …

Zbrush2021写实人物肖像雕刻学习教程

Zbrush 2021写实人物肖像雕刻学习教程 Zbrush 2021 Character Likeness Sculpting Tutorial 大小解压后&#xff1a;24G 持续时间32h 1280X720 MP4 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; 标题:Udemy–Zbrush 2021人物肖像雕刻教程…

监听指定端口数据交互(HttpListenerContext )

很怀念以前做机票的日子&#xff0c;&#xff0c;&#xff0c;&#xff0c;可惜回不去 以前的项目中的&#xff0c;拿来贴贴 场景&#xff1a;同步第三方数据&#xff0c;监听指定地址&#xff08;指定时间间隔&#xff0c;否则不满足&#xff0c;因为需要处理粘包问题&#xf…

OpenCV-Java版学习(1.在IDEA中使用OpenCV)

前言 因为最近要做一个关于计算机视觉的应用程序&#xff0c;所以便来学一下OpenCV的使用&#xff0c;上网找了许久也没找到OpenCV关于Java的教程&#xff0c;无奈之下只能照着官方的Python版的文档学习&#xff0c;所幸里面的函数的使用方法基本都一样。 IDEA中使用OpenCV …

ElasticSearch Groovy脚本远程代码执行漏洞

什么是ElasticSearch&#xff1f;它是一种分布式的、实时性的、由JAVA开发的搜索和分析引擎。2014年&#xff0c;曾经被曝出过一个远程代码执行漏洞&#xff08;CVE-2014-3120&#xff09;&#xff0c;漏洞出现在脚本查询模块&#xff0c;由于搜索引擎支持使用脚本代码&#xf…

2021全国高校计算机能力挑战赛(初赛)Java试题三

二维空间中给定的一组点的坐标&#xff0c;以任意两个点为直径绘制一个圆。求可以绘制的最大圆&#xff0c;满足该圆不包含其他点&#xff0c;输出直径 import java.util.*;import java.util.Scanner; public class Main {private static double res -1;public static void ma…

在Blender中制作火箭发射烟雾和火焰模拟的动画

大小&#xff1a;1.25G 时长1h 30m 1280X720 MP4 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; 在Blender中制作火箭发射烟雾和火焰模拟的动画 Animate a Rocket Launch Smoke & Fire Simulation in Blender 信息: 制作火箭发射的短片…

OpenCV-Java版学习(2.图像入门)

前言 上一篇博客我们讲了如何在IDEA中使用OpenCV来进行一些简单的图像操作&#xff0c;这节我们来学习图像的一些基本的入门级操作。 图像入门 一.在Java中使用OpenCV注意事项 1.解决awt报错问题 先给大家贴个错误&#xff0c;如下图&#xff1a; 我们在使用awt处理图像的…

两个数组找不同

<script> function subArr(a, b) { return a.filter(function(i) { return b.indexOf(i) -1 }) } console.log(subArr([1,2,3,4],[3,4,5])); </script>转载于:https://www.cnblogs.com/mouse2417/p/5165391.html

jQuery Mobile设置边距的宽度和颜色

border-top:10px solid #EFEFF4"

2021全国高校计算机能力挑战赛(初赛)Java试题四

某游戏公司设计了一个奖励活动&#xff0c;给N个用户&#xff08;1<N<10^7&#xff09;连续编号为1到N&#xff0c;依据用户的编号S发放奖励。 import java.util.ArrayList; import java.util.Scanner;public class Main {public static void main(String[] args) {Scann…

Blender与UE5完美结合全流程创作游戏资产视频教程

Blender到虚幻引擎5 Blender to Unreal Engine 5 MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44100 Hz 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; |大小:18.4 GB |时长:20h 55m 只有视频课程 无素材文件 你想学习如何…

OpenCV-Java版学习(3.对视频的基本操作)

前言 上一节我们学习了使用OpenCV对图像进行一些基础操作&#xff0c;现在我们学习对视频进行一些基础的操作。 对视频的基本操作 从相机中读取视频 我们从电脑自带的摄像头捕捉一段视频并在屏幕上显示出来&#xff0c;代码如下&#xff1a; import org.junit.jupiter.api…

win7如何设置某个软件不弹出用户账户控制

手动修改注册表&#xff1a; 在 HKEY_CURRENT_USERS\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers 键下面新建值&#xff0c;值的名字是程序的全路径&#xff0c;值数据是“RunAsInvoker”。 该程序在没有修改系统文件或设置的情况下不会弹出用户帐户控…

IDEA热部署基于maven的web项目

第一步&#xff1a;首先先创建web项目 按照向导一步一步完成项目创建&#xff0c;我创建的示例项目为hotdeploddemo 第二步&#xff1a;设置项目的web资源 下图中的路径要修改正确&#xff0c;指向src/main/webapp/WEB-INF下面的web.xml,然后点击右下角的fix创建artifacts 第三…

2021全国高校计算机能力挑战赛(初赛)C语言试题一

输入两个整数x,y&#xff0c;输出x,y中各位数重新组合的可能形成最小的数。 #include <stdio.h>int main() {int n1, n2, tmp;int s[10000];int i 0;scanf("%d %d", &n1, &n2);while (n1 ! 0) {s[i] n1 % 10;i;n1 n1 / 10;}while (n2 ! 0) {s[i] n…

Unity创建游戏VFX视觉特效-初级到中级

MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44100 Hz 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09;|大小解压后:3.36 GB |时长:4h 17m 本课程是关于用Unity视觉效果图为游戏创建VFX。 你将从零开始学习VFX图形&#xff0…