javascript - 如何在 javascript 中获取 javascript (emberjs) 呈现的 HTML 源
问题描述
问题:我正在开发一个 javascript 扩展,它需要能够在呈现所有内容后查看页面的源 HTML。问题是无论我使用什么方法,我似乎只能检索到预渲染的源。该网站使用 emberjs 生成页面内容。
示例:站点:https ://www.playstation.com/en-us/explore/games/ps4-games/?console=ps4
当我右键单击并查看源代码时,我会在内容加载之前获取页面。当我右键单击并检查元素时,我想在内容加载后获取源代码。
我试过的:
背景.js
var acceptedURLPattern = "playstation.com";
tabUpdatedCallback = function(tabID, changeInfo, tab) {
if(tab.url.indexOf(acceptedURLPattern) == -1) return;
var eventJsonScript = {
code: "console.log(\"Script Injected\"); window.addEventListener(\"load\", (event) => { " + browserString + ".runtime.sendMessage({ \"html\": document.documentElement.outerHTML });});"
};
browser.tabs.executeScript(tabID, eventJsonScript);
}
handleHTMLMessage = function(request, sender, sendResponse) {
console.log(request);
}
browser.tabs.onUpdated.addListener(tabUpdatedCallback);
browser.runtime.onMessage.addListener(handleHTMLMessage);
上面的脚本将一个 eventListener 注入到我想要在它触发“load”事件之后获取源的页面上,然后将一条消息发送回包含该源的 background.js。
我尝试将 documentElement 更改为 innerHTML/outerHTML 以及将 eventListener 更改为 document.addEventListener(\"DOMContentLoaded\"),但这些更改似乎都没有任何效果。
我也尝试过使用这些:使用 phantomjs 获取 javascript 呈现的 html 源并获取浏览器呈现的 html+javascript但他们使用 phantomjs 加载和执行页面,然后返回 html。在我的解决方案中,我需要能够抓取已经呈现的页面。
我在这里先向您的帮助表示感谢!
编辑#1: 我查看了@wOxxOm 提到的 MutationObserver 并将 eventJsonScript 变量更改为如下所示:
var eventJsonScript = {
code: "console.log(\"Script Injected\"); var mutationObserver = new MutationObserver( (mutations) => { mutations.forEach((mutation) => {if( JSON.stringify(mutation).indexOf(\"Yakuza\") != -1) { console.log(mutation); } });}); mutationObserver.observe(document.documentElement, {attributes: true, characterData: true, childList: true, subtree: true, attributeOldValue: true, characterDataOldValue: true}); mutationObserver.takeRecords()"
};
然而,尽管该网站显然有一个 Yakuza 6 的部分,但该事件并没有被解雇。我确实删除了注入脚本中的 if 条件以验证事件是否正常触发,它似乎不包含我正在寻找的信息。
解决方案
所以好消息是有人已经在 Ember 中编写了执行此操作的代码,您可以在这里找到它:
这是 Ember 测试用来等待所有内容呈现并完成或“解决”的代码。
坏消息是为您的扩展正确提取它是一项不平凡的任务。
基本上,你会想要:
- 等到页面加载完毕(window.load 事件)
- setTimeout 至少 200 毫秒以确保 Ember 应用程序已启动。
- 等到解决,使用上面链接的代码。
- 等到浏览器空闲(最新 Chrome 中的 requestIdleCallback 或获取 polyfill)。
希望这有助于您入门。
推荐阅读
- javascript - 嵌套的异步承诺:如何知道它们何时全部解决?
- java - DateTimeFormatter 创建模式
- node.js - 如何使用 Nodejs 和 PassportJS 以及 mongodb 作为数据库来限制每个用户的会话数?
- android - 使用 POST 进行改造会失败,但仍会上传文件
- node.js - Firebase 云功能部署错误“加载用户代码时功能失败”,错误消息为空
- php - 如何在 PHP 中使用搜索选项对多维数组进行排序?
- angular - Ionic 3 - 本地通知弹出/抬头不显示
- c++ - 我们如何将 int* 的地址传递给使用 void ** 作为参数的函数?
- c++ - dynamic_cast 与动态库边界
- c# - Is it possible to share an "enum class" between C++ and C#?