rubinTime
发表于 2022-8-16 22:38:05
哥哥太厉害了,以前看postMessage,总是搞不清楚谁发给谁,这样一看感觉明了了
ozon
发表于 2022-10-11 16:29:13
<blockquote>// ==UserScript==
跨标签页没成功,想要实现在打开搜狗后百度页面改成“打开了搜狗”,不知到那里错了
cxxjackie
发表于 2022-10-11 20:33:00
ozon 发表于 2022-10-11 16:29
跨标签页没成功,想要实现在打开搜狗后百度页面改成“打开了搜狗”,不知到那里错了 ...
你代码没显示出来,是不是顺序错了?应由搜狗向百度发消息:
// ==UserScript==
// @name 跨标签页交互
// @description...
// @namespace ...
// @author ...
// @version 1.0
// @match https://www.baidu.com/*
// @match https://www.sogou.com/*
// @grant none
// @run-at document-idle
// ==/UserScript==
(function() {
'use strict';
if (location.href.includes('baidu')) {
window.open('https://www.sogou.com/');
window.addEventListener('message', e => {
if (e.data.myMessage) {
alert(e.data.myMessage);
}
});
}
if (location.href.includes('sogou') && window.opener) {
window.opener.postMessage({
myMessage: '打开了搜狗'
}, 'https://www.baidu.com');
}
})();
ozon
发表于 2022-10-12 10:04:52
cxxjackie 发表于 2022-10-11 20:33
你代码没显示出来,是不是顺序错了?应由搜狗向百度发消息:
// ==UserScript==
// @name 跨域交互
// @description...
// @namespace ...
// @author ...
// @version 1.0
// @match https://www.baidu.com/*
// @match https://www.sogou.com/*
// @grant none
// @run-at document-idle
// ==/UserScript==
//
(function() {
'use strict';
if (location.href.includes('baidu')) {
window.open('https://www.sogou.com/')
window.addEventListener('message', e => {
if (e.data.magic === true) {
document.body.innerHTML = '打开了搜狗';
}
});
}
setTimeout(()=>{
if (location.href.includes('sogou.com')) {
window.top.postMessage({
magic: true
}, 'https://www.baidu.com');
}
},3500)
})();
昨天下午修改回复后,一提交网页就卡死,访问不了网站,现在好了。对比大佬的代码我知道怎么回事了。感谢c大
挖掘机小王子
发表于 2022-11-9 15:23:27
有时候油猴会Hook两次页面,也是由于存在iframe的原因。
Huan
发表于 2023-2-27 14:58:52
很有用,感谢分享
李恒道
发表于 2023-2-27 16:20:48
突然发现这标题风格极其像我的习惯起名
xiedaolin
发表于 2023-4-5 22:23:20
本帖最后由 xiedaolin 于 2023-4-5 22:25 编辑
> 如果你还不知道什么是同源跨域,请先阅读此文。同源的交互是比较简单的,所有代码可以全放在主页面下处理。主页面先获取iframe所在的元素,iframe.contentWindow即目标window,iframe.contentDocument即目标document,可以用-ment会取到null。解决方法很简单,监听一下iframe的load事件即可,为便于处理,我们可以把这个过程封装一下:
function getIframeDocument(iframe) {
return new Promise(resolve => {
if (iframe.contentDocument) {
resolve(iframe.contentDocument);
} else {
iframe.addEventListener('load', e => {
resolve(iframe.contentDocument);
});
}
});
}
**这里在实际运行我有一个疑问,我获取了iframe 里面的document,可是这个对象只是这一时刻的,也就是说此后的过程中document里面的正在加载别的内容和之前设传递的变量**optDocument**无关了,难道对象不是引用的?**
\` function getOptDocument(iframe) {
console.log("有没有iframe元素了???", iframe);
```
if (iframe) {
return new Promise((resolve, reject) => {
// if (iframe.contentDocument) {
// resolve(iframe.contentDocument);
// // resolve(iframe.contentWindow.document);
// console.log("Run here !!!");
// } else {
// 监听一下iframe的load事件即可
iframe.addEventListener('load', e => {
resolve(iframe.contentDocument);
});
// }
});
} else {
return new Promise((resolve, reject) => {
resolve(document);
});
}
}..then((optDocument) => {
console.log("#main-content ",optDocument.querySelector("#main-content"),
}
```
**在接下来的输出中怎么都获取不到这个元素,就是setTimeout 10秒也不行,后面上半段注释了,使用加载事件可以了**
**我的疑问是,我延迟10秒为什么也不行,从日志输出来看 这个iframe里面的document对象,就是我获取的那一瞬时间的document,为什么不是10秒加载后的,这不是引用类型嘛?**
cxxjackie
发表于 2023-4-6 22:19:47
xiedaolin 发表于 2023-4-5 22:23
> 如果你还不知道什么是同源跨域,请先阅读此文。同源的交互是比较简单的,所有代码可以全放在主页面下 ...
是不是因为iframe的src改变了?比如脚本刚执行时src为空,后面才被赋值,这样的话contentDocument确实会变。
apicinta
发表于 2023-7-14 22:27:49
非常感谢,帮我解决了iframe问题