什么是跨域?如何解决跨域问题?

什么是跨域?如何解决跨域问题?什么是跨域?浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域域名:主域名不同http://www.baidu.com/index.html–>http://www.sina.com/test.js子域名不同http://www.666.baidu.com/index.html–>http://www.555.baidu.co…

大家好,又见面了,我是你们的朋友全栈君。

什么是跨域?
浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域
域名:
 主域名不同 http://www.baidu.com/index.html –>http://www.sina.com/test.js
 子域名不同 http://www.666.baidu.com/index.html –>http://www.555.baidu.com/test.js
 域名和域名ip http://www.baidu.com/index.html –>http://180.149.132.47/test.js
端口:
 http://www.baidu.com:8080/index.html–> http://www.baidu.com:8081/test.js
协议:
 http://www.baidu.com:8080/index.html–> https://www.baidu.com:8080/test.js
备注:
 1、端口和协议的不同,只能通过后台来解决
 2、localhost和127.0.0.1虽然都指向本机,但也属于跨域

跨域限制
1、无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB
2、无法接触非同源网页的 DOM
3、无法向非同源地址发送 AJAX 请求(可以发送,但浏览器会拒绝接受响应)
 
如何解决跨域问题?
跨域实践: Fiddle 处理前端本地开发跨域问题
1、jsonp跨域
JSONP(JSON with Padding:填充式JSON),应用JSON的一种新方法,
JSON、JSONP的区别:
 1、JSON返回的是一串数据、JSONP返回的是脚本代码(包含一个函数调用)
 2、JSONP 只支持get请求、不支持post请求
 (类似往页面添加一个script标签,通过src属性去触发对指定地址的请求,故只能是Get请求)

2、nginx反向代理:
  www.baidu.com/index.html需要调用www.sina.com/server.php,可以写一个接口www.baidu.com/server.php,由这个接口在后端去调用www.sina.com/server.php并拿到返回值,然后再返回给index.html
  
3、PHP端修改header
  header(‘Access-Control-Allow-Origin:*’);//允许所有来源访问
  header(‘Access-Control-Allow-Method:POST,GET’);//允许访问的方式
  
4、document.domain【实现不同window之间的相互访问和操作】
跨域分为两种,一种xhr不能访问不同源的文档,另一种是不同window之间不能进行交互操作;
  document.domain主要是解决第二种情况,且只能适用于主域相同子域不同的情况;
  document.domain的设置是有限制的,我们只能把document.domain设置成自身或更高一级的父域,且主域必须相同。例如:a.b.example.com中某个文档的document.domain可以设成a.b.example.com、b.example.com 、example.com中的任意一个,但是不可以设成c.a.b.example.com,因为这是当前域的子域,也不可以设成baidu.com,因为主域已经不相同了。
兼容性:所有浏览器都支持;
优点:
 可以实现不同window之间的相互访问和操作;
缺点:
 只适用于父子window之间的通信,不能用于xhr;
 只能在主域相同且子域不同的情况下使用;
使用方式:
 不同的框架之间是可以获取window对象的,但却无法获取相应的属性和方法。比如,有一个页面,它的地址是http://www.example.com/a.html , 在这个页面里面有一个iframe,它的src是http://example.com/b.html, 很显然,这个页面与它里面的iframe框架是不同域的,所以我们是无法通过在页面中书写js代码来获取iframe中的东西的:

<script type="text/javascript">
    function test(){ 
   
        var iframe = document.getElementById('ifame');
        var win = document.contentWindow;//可以获取到iframe里的window对象,但该window对象的属性和方法几乎是不可用的
        var doc = win.document;//这里获取不到iframe里的document对象
        var name = win.name;//这里同样获取不到window对象的name属性
    }
</script>
<iframe id = "iframe" src="http://example.com/b.html" onload = "test()"></iframe>

这个时候,document.domain就可以派上用场了,我们只要把http://www.example.com/a.html 和 http://example.com/b.html这两个页面的document.domain都设成相同的域名就可以了。
1.在页面 http://www.example.com/a.html 中设置document.domain:

<iframe id = "iframe" src="http://example.com/b.html" onload = "test()"></iframe>
<script type="text/javascript">
    document.domain = 'example.com';//设置成主域
    function test(){ 
   
        alert(document.getElementById('iframe').contentWindow);//contentWindow 可取得子窗口的 window 对象
    }
</script>

2.在页面 http://example.com/b.html 中也设置document.domain:

<script type="text/javascript">
    document.domain = 'example.com';//在iframe载入这个页面也设置document.domain,使之与主页面的document.domain相同
</script>

5、window.name
关键点:window.name在页面的生命周期里共享一个window.name;
兼容性:所有浏览器都支持;
优点:
 最简单的利用了浏览器的特性来做到不同域之间的数据传递;
 不需要前端和后端的特殊配制;
缺点:
 大小限制:window.name最大size是2M左右,不同浏览器中会有不同约定;
 安全性:当前页面所有window都可以修改,很不安全;
 数据类型:传递数据只能限于字符串,如果是对象或者其他会自动被转化为字符串,如下;
 这里写图片描述
使用方式:修改window.name的值即可;
6、postMessage
关键点:
 postMessage是h5引入的一个新概念,现在也在进一步的推广和发展中,他进行了一系列的封装,我们可以通过window.postMessage的方式进行使用,并可以监听其发送的消息;
兼容性:移动端可以放心用,但是pc端需要做降级处理
优点
 不需要后端介入就可以做到跨域,一个函数外加两个参数(请求url,发送数据)就可以搞定;
 移动端兼容性好;
缺点
 无法做到一对一的传递方式:监听中需要做很多消息的识别,由于postMessage发出的消息对于同一个页面的不同功能相当于一个广播的过程,该页面的所有onmessage都会收到,所以需要做消息的判断;
安全性问题:三方可以通过截获,注入html或者脚本的形式监听到消息,从而能够做到篡改的效果,所以在postMessage和onmessage中一定要做好这方面的限制;
 发送的数据会通过结构化克隆算法进行序列化,所以只有满足该算法要求的参数才能够被解析,否则会报错,如function就不能当作参数进行传递;
使用方式:通信的函数,sendMessage负责发送消息,bindEvent负责消息的监听并处理,可以通过代码来做一个大致了解;

Storage.prototype.sendMessage_ = function(type, params, fn) { 

if (this.topWindow) { 

this.handleCookie_(type, params, fn);
return;
}
var eventId = this.addToQueue_(fn, type);
var storageIframe = document.getElementById('mip-storage-iframe');
var element = document.createElement("a");
element.href = this.origin;
var origin = element.href.slice(0, element.href.indexOf(element.pathname) + 1);
storageIframe.contentWindow.postMessage({ 

type: type,
params: params,
eventId: eventId
}, origin);
}
Storage.prototype.bindEvent_ = function() { 

window.onmessage = function (res) { 

// 判断消息来源
if (window == res.source.window.parent &&
res.data.type === this.messageType.RES &&
window.location.href.match(res.origin.host).length > 0) { 

var fn = this.eventQueue[res.data.eventId];
fn && fn();
delete this.eventQueue[res.data.eventId];
// reset id
var isEmpty = true;
for (var t in this.eventQueue) { 

isEmpty = false;
}
if (isEmpty) { 

this.id = 0;
}
}
}.bind(this);
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/130392.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • SGD随机梯度下降_随机梯度法

    SGD随机梯度下降_随机梯度法BGDvsSGDBGDvsSGD名词解释功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML图表FLowchart流程图导出与导入导出导入BGDvsSGD…

  • java二维数组三种初始化方法(实例)[通俗易懂]

    java二维数组三种初始化方法(实例)[通俗易懂]初始化方法:1、使用大括号直接赋值,适合已经确定知道数组元素的情况2、给定二维数组的大小3、数组第二维的长度可变化,未改变代码举例如下:publicclassNewArray{publicstaticvoidmain(String[]args){//第一种://int[][]arr1=newint[][]…

  • php最新面试题_面试问题汇总

    php最新面试题_面试问题汇总1、酒店预订怎么实现?怎么设计表  你好,我大概的说下我们的业务流程,我们的业务流程是:用户在网站浏览酒店信息,可以根据地区检索出该地区的酒店信息。列表展示酒店的信息由:酒店的名称,酒店图片,酒店位置,评论人数,评论分数以及最低入住价格。用户选中要入住的酒店进入酒店详情页面,查看酒店的介绍以及酒店的房型列表,用户根据他要入住的时间和离店的时间,检索出这个时间段内的所有可选房型(房间数量-当

  • Could not get any response postman报错 但是浏览器可以访问

    Could not get any response postman报错 但是浏览器可以访问答案在最后一张图片案例分析把postman报错的信息复制再这里,你去翻译一下CouldnotgetanyresponseTherewasanerrorconnectingtohttp://118.xxx.xxx.10:11134/api-customer/…

  • MAC IntelliJ IDEA 2018.1版本 安装+破解方法

    一、下载IntelliJIDEA2018.1链接:https://confluence.jetbrains.com/display/IDEADEV/IDEA+2018.1+EAPideaIU-181.4445.20.dmg安装。二、下载包:http://idea.lanyus.com/jar/JetbrainsCrack-2.7-release-str.jar在Finder应用程序文件夹中右击…

  • let/const 的变量提升与暂时性死区

    let/const 的变量提升与暂时性死区在面试或一些文章中提到var和let/const区别时,总说var有变量提升,let/const不存在变量提升,这种说法是错误的.var和let/const都有变量提升,但是let/const暂时性死区的存在要求调用该类变量前必须先经过显式赋值

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号