有关跨域问题的原因 及 解决办法【转】
来源:互联网 发布:自己制作名片软件 编辑:程序博客网 时间:2024/05/22 01:26
出现原因
- 【出现原因】什么是跨域以及产生原因
跨域是指a页面想获取b页面资源,如果a、b页面的协议、域名、端口、子域名不同,或是a页面为ip地址,b页面为域名地址,所进行的访问行动都是跨域的,而浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源。
Uri 说明 是否跨域 http://www.cnblogs.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主域名相同 子域名不同是(cookie不可访问)http://www.a.com/a.js
http://a.com/b.js同一域名,不同二级域名(同上)是
解决方案
- 【策略一】Jsonp 需要目标服务器配合一个callback函数
JSONP(JSON with Padding)是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过JavaScript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。
Json+padding(内填充),顾名思义,就是把JSON填充到一个盒子里,它的基本思想是,网页通过添加一个
<script>
元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。
首先,网页动态插入<script>
元素,由它向跨源网址发出请求。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 【策略二】通过修改document.domain来跨子域
将子域和主域的document.domain设为同一个主域.前提条件:这两个域名必须属于同一个基础域名!而且所用的协议,端口都要一致,否则无法利用document.domain进行跨域
主域相同的使用document.domain
- 【策略三】使用window.name来进行跨域
.window.name+iframe 需要目标服务器响应window.name,window对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的!
javascript
window.name = data;
//接着,子窗口跳回一个与主窗口同域的网址。
location = 'http://parent.url.com/xxx.html';
//然后,主窗口就可以读取子窗口的window.name了
var data = document.getElementById('iframe').contentWindow.name;
优点:window.name容量很大,可以防止非常长的字符串;
缺点:必须监听子窗口window.name属性的变化,会影响网页性能。
- 【策略四】跨文档消息传输window.postMessage上面两种方法都属于破解,HTML5为解决这个问题,引入一个全新的API:跨文档消息传输Cross Document Messaging。
下一代浏览器都将支持这个功能:Chrome 2.0+、Internet Explorer 8.0+, Firefox 3.0+, Opera 9.6+, 和 Safari 4.0+ 。
Facebook已经使用了这个功能,用postMessage支持基于web的实时消息传递。使用方法:otherWindow.postMessage(message, targetOrigin);
otherWindow: 对接收信息页面的window的引用。可以是页面中iframe的contentWindow属性;window.open的返回值;
通过name或下标从window.frames取到的值。
message: 具体的信息内容,string类型。
targetOrigin: 接受消息的窗口的源(origin),即“协议+域名+端口”。也可以设为“*”,表示不限制域名,向所有窗口发送。
message事件的事件对象event,提供一下三个属性:
(1).event.source:发送消息的窗口
(2).event.origin:消息发向的网站
(3).event.data:消息内容
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
【策略五】通过CORS解决AJAX跨域
CORS是跨源资源分享(Cross-Origin Resource Sharing)的缩写。它是W3C标准,是跨源AJAX请求的根本解决方法。相比JSONP只能发GET请求,CORS允许任何类型的请求。
定义:CORS其实出现时间不短了,它在维基百科上的定义是:跨域资源共享(CORS)是一种网络浏览器的技术规范,它为Web服务器定义了一种方式,允许网页从不同的域访问其资源。而这种访问是被同源策略所禁止的。CORS系统定义了一种浏览器和服务器交互的方式来确定是否允许跨域请求。 它是一个妥协,有更大的灵活性,但比起简单地允许所有这些的要求来说更加安全。而W3C的官方文档目前还是工作草案,但是正在朝着W3C推荐的方向前进。简言之,CORS就是为了让AJAX可以实现可控的跨域访问而生的。
以往的解决方案:
以前要实现跨域访问,可以通过JSONP、Flash或者服务器中转的方式来实现,但是现在我们有了CORS。
CORS与JSONP相比,无疑更为先进、方便和可靠。
1、 JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。
2、 使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。
3、 JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS(这部分会在后文浏览器支持部分介绍)。
【策略六】通过设置Access-Control-Allow-Origin
在被请求的Response header中加入 :
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
就可以实现ajax POST跨域访问了。
客户端请求:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
服务器端处理:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
Access-Control-Allow-Origin:* 表示允许任何域名跨域访问
如果需要指定某域名才允许跨域访问,只需把Access-Control-Allow-Origin:*改为Access-Control-Allow-Origin:允许的域名
例如:header(‘Access-Control-Allow-Origin:http://www.client.com‘);如果需要设置多个域名允许访问,这里需要用PHP处理一下
例如允许 www.client.com 与 www.client2.com 可以跨域访问服务器端处理:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
之前我们跨域是借助了浏览器对 Access-Control-Allow-Origin 的支持。但有些浏览器是不支持的,所以这并非是最佳方案,现在我们来利用nginx 通过反向代理 满足浏览器的同源策略实现跨域!
然后我们回到nginx.conf 配置一个反向代理路径(location /apis部分):
- 有关跨域问题的原因 及 解决办法【转】
- Fragment 重叠问题的原因及解决办法
- 有关安装MyEclipse6.0后启动异常的原因及解决办法。
- JBPM deploy processdefinition 报错的问题原因及解决办法
- web项目中的乱码问题的原因及解决办法
- SpringObjectFactory.java:220:-1问题出现的原因及解决办法
- 网络丢包问题的原因及解决办法
- DjangoUnicodeDecodeError有关问题的解决办法
- 有关AJAX跨域的解决办法-JSONP
- 有关AJAX跨域的解决办法-JSONP
- WINDOWS域用户登录慢的原因及解决办法
- WINDOWS域用户登录慢的原因及解决办法
- 【转】+【原】EXCEL文件过大的原因及解决办法
- 【转】蓝屏代码0X0000007B的原因及解决办法
- 【转】MYSQL安装失败的原因及解决办法
- 转:java.lang.IllegalStateException异常产生的原因及解决办法
- 安装 VS2005 SP1 有关问题的解决办法
- 有关手机中文问题传输的解决办法
- 卫星图像分割--Effective Use of Dilated Convolutions for Segmenting Small Object Instances
- New Study
- maven导包不当的error
- 关于头文件中的 static inline函数
- 带方括号的字符串如何转换成json对象
- 有关跨域问题的原因 及 解决办法【转】
- jQuery微信手机端九宫格抽奖代码特效
- 现象级
- mybatis generator的使用及自定义sql最佳实践
- ittun 在虚拟机中配置使用
- Redis源码剖析--压缩列表
- JavaWEB的Servlet
- Linux运维学习之路(7)进程管理
- Codeforces Round #433 (Div.2)