如何自动填充iframe内表单字段?求书签脚本实现方案
解决iframe内表单自动填充问题并做成Bookmarklet
问题根源
你的原代码只在主页面的上下文里查找表单元素,而iframe是独立的浏览器上下文,有自己的window和document对象,所以原代码碰不到iframe里的表单。
修改方案
把填充逻辑抽成独立函数,同时遍历页面上所有同源iframe,在每个iframe的上下文里执行填充逻辑,主页面本身也执行一次。
修改后的完整代码
(function() { "use strict"; // 定义填充逻辑,接收目标document对象 function fillForms(targetDoc) { var fieldValueMap = { "author": "author", "name": "name", "email": "email@gmail.com", "url": "url.link", "website": "website.com", "comment": "comment", "commentName": "commentName", "commentEmail": "commentEmail@gmail.com", "commentWebsite": "commentWebsite.com", "commentComment": "commentComment" }; Object.keys(fieldValueMap).forEach(function(name) { var input = targetDoc.querySelector("form input[id='" + name + "']") || targetDoc.querySelector("form select[id='" + name + "']") || targetDoc.querySelector("form textarea[id='" + name + "']"); if (input && input.type !== "hidden") { input.value = fieldValueMap[name]; } }); } // 填充主页面表单 fillForms(document); // 遍历所有iframe,填充同源iframe内的表单 var iframes = document.querySelectorAll("iframe"); for (var i = 0; i < iframes.length; i++) { try { // 尝试访问iframe的document,跨域会抛出异常 var iframeDoc = iframes[i].contentDocument || iframes[i].contentWindow.document; fillForms(iframeDoc); } catch (e) { // 跨域iframe无法访问,直接跳过 continue; } } })();
关键说明
- 把填充逻辑封装成
fillForms函数,参数是目标document,这样既可以传主页面的document,也可以传iframe的document - 遍历所有iframe时,用
try-catch处理跨域情况——浏览器禁止JS访问跨域iframe的内容,这是安全限制,没法绕过,碰到跨域的iframe直接跳过即可 - 兼容两种获取iframe document的方式:
contentDocument(标准)和contentWindow.document(旧IE兼容)
转成Bookmarklet
要做成书签小工具,需要把代码压缩成一行,前缀加javascript::
- 用JS压缩工具把代码压缩成无换行的紧凑格式
- 在压缩后的代码最前面加上
javascript: - 把整串内容作为书签的URL保存
压缩后的示例(可自行重新压缩确保最新):
javascript:(function(){"use strict";function t(t){var e={"author":"author","name":"name","email":"email@gmail.com","url":"url.link","website":"website.com","comment":"comment","commentName":"commentName","commentEmail":"commentEmail@gmail.com","commentWebsite":"commentWebsite.com","commentComment":"commentComment"};Object.keys(e).forEach(function(n){var o=t.querySelector("form input[id='"+n+"']")||t.querySelector("form select[id='"+n+"']")||t.querySelector("form textarea[id='"+n+"']");o&&"hidden"!==o.type&&(o.value=e[n])})}t(document);for(var e=document.querySelectorAll("iframe"),n=0;n<e.length;n++)try{var o=e[n].contentDocument||e[n].contentWindow.document;t(o)}catch(i){}})();
注意事项
- 只有同源的iframe(和主页面域名、协议、端口完全一致)才能被填充,跨域iframe受浏览器安全限制无法操作
- 部分网站可能有内容安全策略(CSP)禁止书签脚本执行,这种情况属于网站安全限制,无法绕过
内容的提问来源于stack exchange,提问作者synthetic.gxd
相关产品推荐
相关产品推荐

