JavaScript跨域方式总结
1. jsonp请求
jsonp的原理是利用 script 标签的跨域特性,可以不受限制地从其他域中加载资源,类似的标签还有 img。
缺点:只支持GET请求而不支持POST等其他类型的HTTP请求。
<script>
//回调函数,用来发送给 php服务器
function getData(data) {
console.log(data);
}
//核心本质 就是后端服务器 返回一个函数调用 getData('js')
createJsonp();
function createJsonp() {
const s = document.createElement('script');
s.src='http://localhost/data.php?callback=getData';
document.body.appendChild(s);
}
</script>
<?php
//跨域必须允许,后台说了管用
//header('Access-Control-Allow-Origin:*');
$receive=$_GET["callback"]; // 拿到回调函数,可以用来判断
$arr = [
[
'id'=>1,
'name'=>'追梦',
'age'=>18
],
[
'id'=>2,
'name'=>'阿飞',
'age'=>18
]
];
//编译成字符串
echo json_encode($arr);
?>
2. document.domain
这种方法用在主域名相同子域名不同的跨域访问中。举个例子:http://a.frame.com和http://b.frame.com 他们的主域名都是frame.com 这两个域名中的文件可以用这种方式进行访问,通过在两个域中具体的文件中设置document.domain="frame.com"就可达到跨域访问的目的。
实际应用中常常用在iframe中窗口之间的访问,根据浏览器的同源策略,浏览器中不同域的框架之间是不能进行js的交互操作的,所以一个窗口是不能拿到另一个窗口中的contentWindow对象的属性和方法的(注意是能拿到contentWindow对象的,只是属性和方法都不可用)。
为了能拿到数据,只要在两个iframe中分别写入document.domain="主域名",这样设置之后,就能拿到contentWindow对象的属性和方法了。
3. window.name
window的name属性有个特征:在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口在载入过的所有页面中的,并不会因新页面的载入而进行重置。
比如我在a.html这个页面中设置了window.name="a";然后让window重新加载b.html页面,然后在b.html页面中输出window.name会发现window.name=“a”。所以就算a.html和b.html这两个页面不是在同一个域中的,也可以在b页面中拿到a页面设置的window.name的值,跨域的核心思路就是这个原理。
例子:getDomainData.html是获取数据的页面,null.html是一个和getDomainData.html同域的空页面,它的作用是作为一个中转站,进行数据的过渡。data.html是要获取数据的所在页面,这里有着我们要的数据,它和getDomainData.html处于不同域中,所以取数据是跨域访问。
具体的过程是这样的:在getDomainData.html中建立一个子页面iframe,把这个iframe的src指向b.com/data.html,这样当这个iframe加载完成后就可以访问到data.html中的window.name的数据,之后再将iframe的src改为a.com/null.html,跳回getDomainData.html的同一个域,这样根据同源策略,getDomainData.html就可以访问到null.html中取得的data.html的数据了。获取数据以后最好销毁这个iframe,释放掉内存,也保证了安全。
getDomainData.html:
<script type="text/javascript">
var flag=0;
var data;
var iframe=document.createElement("iframe");//创建一个中转站iframe
document.appendChild(iframe);
getData=function(){ //iframe加载完成后调用的处理函数
if(flag==1){
data=iframe.contentWindow.name; //读取b.html中的window.name
}else{
flag=1;
iframe.src="http://a.com/null.html";//跳回getDomainData.html的同一个域
}
};
iframe.src="http://b.com/data.html";//设置src到要获得数据的域中的对应页面
if (iframe.attachEvent) { //兼容IE,监听iframe加载完成
iframe.attachEvent('onload', getData);
} else {
iframe.addEventListener('load',getData);
}
</script>
data.html:
<script>
window.name="被获取数据"//简单的一行代码
</script>
最后的iframe销毁:
<script>
iframe.contentWindow.document.write(""); //情况iframe中的内容
iframe.contentWindow.close(); //避免iframe的内存泄漏
document.body.removeChild(iframe); //移除iframe节点
</script>
4. window.postMessage
window.postMessage是html5中实现跨域访问的一种新方式,可以使用它来向其它的window对象发送消息,无论这个window对象是否属于同源或不同源。
5. CORS
使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是应该失败。
6. Web Sockets
在js创建了web socket之后,会有一个HTTP请求发送到浏览器以发起连接。取得服务器响应后,建立的连接会使用HTTP升级从HTTP协议交换为web socket协议。
详情参见大佬总结:https://segmentfault.com/a/1190000008525104
JavaScript跨域方式总结的更多相关文章
- JavaScript 跨域:window.postMessage 实现跨域通信
JavaScript 跨域方式实现方式有很多,之前,一篇文章中提到了 JSONP 形式实现跨域.本文将介绍 HTML5 新增的 api 实现跨域:window.postMessage . 1 othe ...
- Javascript几种跨域方式总结
在客户端编程语言中如javascript,同源策略规定跨域之间的脚本是隔离的,一个域的脚本不能访问和操作另外一个域的绝大部分属性和方法.只有当两个域具有相同的协议,相同的主机,相同的端口时,我们就认定 ...
- JavaScript跨域解决方式
平时工作中经常被JavaScript跨域问题所困扰,其实有很多种解决方式,下面给大家介绍常用的几种: 1.jsonp解决跨域问题 客户端代码: <!DOCTYPE html> <ht ...
- 「JavaScript」四种跨域方式详解
超详细并且带 Demo 的 JavaScript 跨域指南来了! 本文基于你了解 JavaScript 的同源策略,并且了解使用跨域跨域的理由. 1. JSONP 首先要介绍的跨域方法必然是 JSON ...
- 「JavaScript」JS四种跨域方式详解
原文地址https://segmentfault.com/a/1190000003642057 超详细并且带 Demo 的 JavaScript 跨域指南来了! 本文基于你了解 JavaScript ...
- JavaScript 跨域漫游
前言: 最近在公司做了几个项目都涉及到了iframe,也就是在这些iframe多次嵌套的项目中,我发现之前对iframe的认识还是比较不足的,所以就静下心来,好好整理总结了iframe的相关知识:&l ...
- 利用javascript跨域访问cookie之广告推广
在上一篇<说一说javascript跨域和jsonp>中,利用JSONP进行了跨域的数据访问,利用JS本身的跨域能力在远端生成HTML结构的方式完成了一个小广告. 在实际应用中, 跨域使用 ...
- 优雅绝妙的Javascript跨域问题解决方案
关于Javascript跨域问题的解决方案已在之前的一片文章中详细说明,详见:http://blog.csdn.net/sfdev/archive/2009/02/13/3887006.aspx: 除 ...
- JavaScript跨域实现
最近在做个上传文件的服务,其中包含一个上传的web页面.目的是想客户端页面嵌套这个web页面,然后直接将文件上传到服务器. 因为文件不同所以需要保存到的文件夹名称也不一样,所以客户端需要传递一个文件夹 ...
随机推荐
- HDU 4886 TIANKENG’s restaurant(Ⅱ) ( 暴力+hash )
TIANKENG’s restaurant(Ⅱ) Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 130107/65536 K (Ja ...
- MVC的实体模型写在类库,为什么被其他类库调用时,用不了模型的表?
一,很简单,由于第一次添加实体模型时,VS会自动帮你添加引用System.Data.Entity到当前类库,如下图示: 二,而手动添加的类库并不存在这个引用,则及时你引用了当前的实体模型的类库,却使用 ...
- Java模拟HttpClient进行Get和Post提交
使用Java模拟客户端进行提交,需要用到apache http client jar,这里用的是4.4版本 GET: public void GetURL(){ String strResp=&qu ...
- Ubuntu18.04安装Tensorflow1.14GPU
软件要求 必须在系统中安装以下 NVIDIA® 软件: https://www.pytorials.com/how-to-install-tensorflow-gpu-with-cuda-10-0-f ...
- 59th python下graphviz安装 砖
原文 摘录 感谢分享: https://www.cnblogs.com/liusx0303/p/9155305.html 参考链接:https://blog.csdn.net/u01325041 ...
- 深入理解TCP协议及其源代码
本次实验,我们来探究connect及bind.listen.accept背后的三次握手. 实验原理 首先简要回顾一下TCP三次握手的过程: 第一次握手:client向server发送SYN=1的数据报 ...
- eclipse里部署struts2
Struts2是一个比较出色的基于MVC设计模式的框架,是由Struts1和WebWork发展而来的,性能也比较稳定,现在是Apache软件基金会的一个项目,下面就来配置Struts2进行初始化的开发 ...
- Qt 显示网页的控件
Qt5.6以下的版本,基于QtWebkit控件Qt5.6以上的MSVC版本,基于 Chromium 的浏览器引擎 Qt WebEngineQt5.6以上的mingw 版本,只能采用QAxWidget ...
- TCP/IP的分层管理_01
1.TCP/IP协议族里最重要的一点就是分层.TCP/IP协议族按层次分别分为以下4层: 应用层,传输层,网络层和数据链路层. 应用层:决定了向用户提供应用服务时通 ...
- JAVA 输入输出程序开发
参考: java中 静态方法和非静态方法的区别 字符流的输入和输出 java文件创建.删除.读取.写入操作大全 Java键盘输入并且写入文件 File类的isDiretory Java统计子串在字符串 ...