iframe中访问easyui的jsp页面时脚本的正确写法
很多初学Easyui的人都会遇到这样的问题,那就是在页面中采用iframe标签后,当直接指定src页面是一个采用了easyui组件的页面,当parent窗口需要访问iframe中的对象时,不应该采用document的访问,而应该访问iframe的对象,这样才能用easyui中的标准api访问对象的属性和方法,具体访问方法如下两种:
1、document.getElementById(’ss_frame’).contentWindow.$(’#dgMANUF’).datagrid(’getSelected’);
2、$.find(’iframe’).contentWindow.$(’#dgMANUF’).datagrid(’getSelected’);
请不要使用$(’#ss_frame’).contentWindow.$(’#dgMANUF’).datagrid(’getSelected’);这样的代码,因为在JQuery中无法正确返回对象,系统会提示“无法获取属性“nodeName”的值:
对象为
null
或未定义
Error”之类的错误。
访问对象的问题解决以后就会带来另外一个问题,iframe的刷新问题,因为可能大家会采用动态页面,我们看到很多解决方案说只要将对象的src修改就可以正确显示,但是我们发现系统会有一个延迟,而这对于脚本客户端会有致命的错误。解决的方法其实很简单,那就是直接让iframe的对象输出一个提示,直到页面加载完毕。具体解决代码如下:
document.getElementById(’ss_frame’).contentWindow.document.write(’loading…’);
怎么在html页面中获得iframe元素中的window对象
每个框架都有一个window对象. $(“iframe“).contentWindow返回的确实是框架window对象.
怎么解决跨域问题
1、 通过jsonp跨域
JSONP(JSON with Padding:填充式JSON),应用JSON的一种新方法,
JSON、JSONP的区别:
1、JSON返回的是一串数据、JSONP返回的是脚本代码(包含一个函数调用)
2、JSONP 只支持get请求、不支持post请求
(类似往页面添加一个script标签,通过src属性去触发对指定地址的请求,故只能是Get请求)
2、代理:
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
跨域分为两种,一种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,因为这是当前域的子域,也不可以设成ba
1.在页面 《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.在页面 《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;
fn && fn();
delete this.eventQueue;
// reset id
var isEmpty = true;
for (var t in this.eventQueue) {
isEmpty = false;
}
if (isEmpty) {
this.id = 0;
}
}
}.bind(this);
}
无法获取contentWindow
可能是因为页面没有加载完, 就执行获取了
$(’ifame’).onload = function () {
//在这执行试试看.
}
jquery 在父页面中如何获取子页面中的对象
两点
1.既然你用jQuery了,为什么还要用getElementById()来获取元素?况且,获取iframe中元素也没这么麻烦啊
$(“#id_iframe“).contents().find(“#id_button_test“);
这不就好了。。
2.你这部分代码是写在a.jsp页面中了吧?那我估计之所以不运行,是因为你注册点击事件的时候,b.jsp页面还没有加载完。所以尽管你调试的时候能输出,但是代码里是注册不上的。把这段代码写在b.jsp的window.onload事件中
怎么获取不了iframe中的对象
1、你取得iframe的document的前提为这个iframe的地址是你域内的页面,比如你设src为百度,取这个iframe的document时就会报拒绝访问的错误2、我试过了 document.getElementById(’myf’).contentWindow.document 在ie与谷歌都行的3、document.frames(’iframename’).document 这个方法只能在ie下面取得到4、用火狐的firebug看看吧,有什么错都会显示出来,莫名其妙的事情什么时候都可能发生,有时我直接取取window都报undefined
js报错:为空或不是对象
判断是否加载完成可以查看子页面的参数 iframe.contentWindow.某属性
在子页面的onload方法力给参数赋值
如果参数=你所期望的值,表示加载完成=》执行操作
如果参数!=你所期望的值,给多少时间段再去检查,用setTimeOut就可以了,间隔不要太长,200mm左右
跨域问题解决方法
跨域?他是浏览器的 同源策略 造成的,是浏览器对javascript施加的安全限制。所谓同源是指:域名、协议、端口均相同。
解决
原理:利用标签具有可跨域的特性,可实现跨域访问接口,需要后端的支持。
服务器在收到请求后,解析参数,计算返还数据,输出messagetow(data)字符串。
缺点:只能发送get请求,无法访问服务器的响应文本(单向请求),即只能获取数据不能改数据。
通过ajax请求不同域的实现,底层不是靠XmlHttpRequest而是script,所以不要被这个方法给迷惑了。
在aja
同源策略是针对浏览器端进行的限制,可以通过服务器端来解决该问题,例如nginx
DomainA客户端(浏览器) ==》 DomainA服务器 ==》 DomainB服务器 ==》 DomainA客户端(浏览器)
iframe获取document问题,火狐下获取contentWindow.document失效
尊敬的用户,您好!很高兴为您答疑。
target = ’hiddeFrame’的意思是在名称叫做hiddeFrame的框架中开启,那么contentWindow.document的意思是在名叫contentWindow的框架中获取document对象。
希望我的回答对您有所帮助,如有疑问,欢迎继续咨询我们。