jwa*_*980 5 html javascript iframe dom
我有几个后端 Salesforce (SF) 页面,它们具有很长的下拉列表(例如最多 1,000 个选项),并且我想在 Chrome 书签中使用 JS 代码将过滤器框添加到页面上的任意 SELECT 中(代码如下)。我认为问题是因为我想要访问的节点位于名为 的自定义 HTML 元素内force-aloha-page。
就我而言,我想要访问的第一个元素是自定义元素内的 IFRAME。(这不是一个跨站点安全问题,因为即使来源不好,JS 仍然会获得 IFRAME,只是其中没有任何内容。)
\n\n例如,我可以检查代码并查看自定义 HTML 元素、查看 iframe,并且可以在页面上查看 iframe 的内容。如果我只是将节点转储到控制台,它会显示 JS 无法访问的 DOM 元素:
\n\n\n\n\n\n
\n- \n
document.getElementsByTagName("FORCE-ALOHA-PAGE")[0]- \n
<force-aloha-page data-data-rendering-service-uid=\xe2\x80\x8b"203" data-aura-rendered-by=\xe2\x80\x8b"505:\xe2\x80\x8b0" force-alohapage_alohapage-host>\xe2\x80\x8b<div force-alohapage_alohapage class=\xe2\x80\x8b"iframe-parent slds-template_iframe slds-card">\xe2\x80\x8b<iframe force-alohapage_alohapage height=\xe2\x80\x8b"100%" width=\xe2\x80\x8b"100%" scrolling=\xe2\x80\x8b"yes" allowtransparency=\xe2\x80\x8b"true" name=\xe2\x80\x8b"vfFrameId_1569557364522" title=\xe2\x80\x8b"Page Configuration" allowfullscreen=\xe2\x80\x8b"true" lang=\xe2\x80\x8b"en-US" allow=\xe2\x80\x8b"geolocation *;\xe2\x80\x8b microphone *;\xe2\x80\x8b camera *">\xe2\x80\x8b\xe2\x80\xa6\xe2\x80\x8b</iframe>\xe2\x80\x8b</div>\xe2\x80\x8b</force-aloha-page>\xe2\x80\x8b
我可以看到元素内部的div和。但是,如果我尝试访问 iframe,就会发生这种情况:iframeforce-aloha-page
\n\n\n\n
\n- \n
document.getElementsByTagName(\'IFRAME\')- \n
0- \n
document.querySelectorAll("iframe")- \n
0
JS可以看到自定义元素:
\n\n\n\n\n\n
\n- \n
document.getElementsByTagName("FORCE-ALOHA-PAGE").length- \n
1
但里面什么也没有:
\n\n\n\n\n\n
\n- \n
document.getElementsByTagName("FORCE-ALOHA-PAGE")[0].childNodes.length- \n
0
即使上面的“节点转储”有效,但这不起作用:
\n\n\n\n\n\n
\n- \n
document.getElementsByTagName("FORCE-ALOHA-PAGE")[0].innerHTML- \n
""
一旦我到达 iframe,我可能会遇到一个完整的其他问题,但我必须首先克服该自定义标记。
\n\n我尝试过的
\n\n我在 Chrome 中创建了 JS 书签,它适用于主页中的 SELECT 和具有良好 XSS 的 IFRAME 内部。但不适用于自定义标签内的 SELECT。这是我在编写书签代码时使用的测试页。
\n\n测试页1.html
\n\n<html>\n<body>\n<select>\n <option value="1">1</option>\n <option value="10">10</option>\n <option value="2">2</option>\n <option value="20">20</option>\n</select>\n<br /><br />\n<select>\n <option value="Apples">Apples</option>\n <option value="Berries">Berries</option>\n <option value="Candies">Candies</option>\n <option value="Danishes">Danishes</option>\n</select>\n<br /><br />\n<iframe src="testpage2.html"></iframe>\n</body>\n</html>\nRun Code Online (Sandbox Code Playgroud)\n\n测试页2.html
\n\n<html>\n<body>\n<select>\n <option value="3">3</option>\n <option value="30">30</option>\n <option value="4">4</option>\n <option value="40">40</option>\n</select>\n<br /><br />\n<select onchange="selectChange(this)">\n <option value="Eclaires">Eclaires</option>\n <option value="Frozen Custard">Frozen Custard</option>\n <option value="Grapes">Grapes</option>\n <option value="Heath Bar">Heath Bar</option>\n</select>\n<script type="text/javascript">\n function selectChange(el) {\n console.log("Select value: " + el.value);\n }\n</script>\n</body>\n</html>\nRun Code Online (Sandbox Code Playgroud)\n\n书签代码(为了更好的可读性而展开):
\n\njavascript:(function(){\n //return an array of all selects in the main page or in iframes\n var selects=function(d){\n var a=[],\n s=d.getElementsByTagName(\'SELECT\'),\n b=d.getElementsByTagName(\'IFRAME\');\n for(var i=0;i<s.length;i++)\n a.push(s[i]);\n for(var i=0;i<b.length;i++){\n try{\n a=a.concat(selects(b[i].contentWindow.document));\n }catch(e){\n console.log(e);\n }\n }\n return a;\n },\n //makes the SELECT border blink and scrolls it into view\n blink=function(els,i){\n if(i>=els.length)return;\n var el=els[i],s=el.style,t=200,\n nb=\'3px solid blue\',eb=s.border+\'\';\n el.scrollIntoView();\n s.border=nb;\n setTimeout(function(){s.border=eb;},t);\n setTimeout(function(){s.border=nb;},t*2);\n setTimeout(function(){\n s.border=eb;\n if(confirm("This one?")){\n filter(el);\n }else{\n blink(els,i+1);\n }\n },t*3);\n },\n //helper for creating options on a select\n opt=function(v,t,p){\n var y=document.createElement(\'OPTION\');\n y.value=v;\n y.text=t;\n p.appendChild(y);\n },\n //creates the new filter input and adds it to the page\n filter=function(el){\n console.log(\'Filtering...\');\n var d=document,c=d.createElement(\'INPUT\'),o=[];\n c.type=\'text\';\n c.placeholder=\'Filter list\';\n c.style.width=el.style.width;\n c.style.display=\'block\';\n el.parentNode.insertBefore(c,el);\n //filters the option list when something is typed\n c.onkeyup=function(ev){\n var j=c.value+\'\',h=el.options,x=0;\n if(o.length==0){\n for(var e=0;e<h.length; e++){\n with(h[e]){\n o.push({\'v\':value,\'t\':text});\n }\n }\n }\n for(var g=h.length-1;g>=0;g--)el.remove(g);\n for(var i=0;i<o.length; i++){\n if(j.length==0){\n opt(o[i].v,o[i].t,el);\n }else{\n if(match(o[i].t,j)){\n if(x==0) opt(\'\',\'\',el);\n opt(o[i].v,o[i].t,el);\n x++;\n }\n }\n }\n if(x>0) el.options[0].text=\'<\'+x+\' Match(es) Found>\';\n };\n },\n //determines if the option text matches the filter criteria, with wildcard support\n match=function(a,b){\n a=(a+\'\').toLowerCase();\n b=(b+\'\').toLowerCase();\n if(b.indexOf(\'*\')<0){\n return a.indexOf(b)>=0;\n }else{\n var r=\'.*\',c=b.split(\'*\');\n for(var i=0;i<c.length;i++){\n r+=\'.*\'+(c[i].length>0?\'(\'+c[i]+\')\':\'\');\n }\n r+=\'.*\';\n return (new RegExp(r)).test(a);\n }\n },\n d=document,s=selects(d),v=[];\n //gets only SELECTs that are visible on the page\n for(var i=0;i<s.length;i++){\n if (window.getComputedStyle(s[i]).display !== \'none\') \n v.push(s[i]);\n }\n console.log(\'SELECTs: \'+s.length);\n console.log(\'Visible SELECTs: \'+v.length);\n //Begin.\n blink(v,0);\n})();\nRun Code Online (Sandbox Code Playgroud)\n\n在我的 JS 代码中,我还尝试创建一个递归函数来爬行所有子节点,但是,正如我上面发布的控制台示例所示,JS 为自定义元素返回 0 个子节点。
\n该force-aloha-page元素可能是一个Web 组件,这可能解释了为什么您无法访问内部的 DOM,因为它是Shadow DOM。
尝试使用属性来访问它shadowRoot,如下所示:
class ForceAlohaPage extends HTMLElement {
constructor() {
super();
this.attachShadow({
mode: 'open'
}).innerHTML = '<iframe force-alohapage_alohapage height="100%" width="100%" scrolling="yes" allowtransparency="true" name="vfFrameId_1569557364522" title="Page Configuration" allowfullscreen="true" lang="en-US" allow="geolocation *; microphone *; camera *"></iframe>';
}
}
customElements.define("force-aloha-page", ForceAlohaPage);
console.log(document.getElementsByTagName('iframe').length);
console.log(document.getElementsByTagName("force-aloha-page")[0].childNodes.length);
console.log(document.getElementsByTagName("force-aloha-page")[0].innerHTML);
console.log(document.getElementsByTagName('force-aloha-page')[0].shadowRoot.childNodes[0]);Run Code Online (Sandbox Code Playgroud)
<force-aloha-page></force-aloha-page>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1388 次 |
| 最近记录: |