覆盖 console.log 等以在 HTML 视图中显示

Overriding console.log, etc to display inside HTML view

所以,我正在做一个项目,在这个项目中,实际生产环境可以访问 APIs,除了在生产环境中加载页面(他们正在使用 angular.$window.external),但在生产环境中加载页面意味着我无法访问开发人员工具、控制台等,因为它 运行 在应用程序内浏览器实例中。因此,我试图将所有控制台 log/etc 语句输出到文档中的 div 中,以尝试在我的 API 调用未按预期工作时进行故障排除。

我可以正常使用它,但它遗漏了一些东西,我不确定为什么。

我包含的代码为 consoledebug.js:

// Code adapted from 
// Include consoledebug.js at the end of a file, and create a div with
// the id "logs" in your html file where you want output.

var logDiv = document.getElementById('logs')

var addToLogDiv = function (type, text) {
  var node = document.createElement('p')
  node.className = type
  var content = document.createTextNode(type + ': ' + text)
  node.appendChild(content)
  logDiv.appendChild(node)
}

// define a new console
var console = (function (oldCons) {
  return {
    log: function (text) {
      oldCons.log(text)
      addToLogDiv('log', text)
    },
    info: function (text) {
      oldCons.info(text)
      addToLogDiv('info', text)
    },
    warn: function (text) {
      oldCons.warn(text)
      addToLogDiv('warn', text)
    },
    error: function (text) {
      oldCons.error(text)
      addToLogDiv('error', text)
    }
  }
})(window.console)

//Then redefine the old console
window.console = console

我将 <script src="../common/consoledebug.js"></script> 标签放在 HTML 文档的末尾,就在 </body> 标签之前。

当我 运行 在常规 chrome window 中时,我在 HTML 正文中得到这些行:

log: test

error: TypeError: $window.external.SomeProprietaryAPI is not a function

但是 Chrome 的日志显示了一个额外的错误 myhtml.html:35 Uncaught ReferenceError: someOtherProprietaryAPI is not defined at myhtml.html:35

关于为什么我的函数没有捕获到它或者我可以做些什么有什么建议吗?或者将 all 控制台输出输出到 HTML 文档本身的替代方法?

我尝试在文件顶部包含脚本,但所做的只是给了我 2 个无法附加到 null 的错误(对于它捕获的 2 个日志条目,但不是第三个它不是)。

我是 Javascript 的新手,正在尝试获取现有 AngularJS 代码的基础,以便在新版本的生产环境中工作,该生产环境已从使用 IE 切换到 Chromium HTML显示.

编辑:在 Plunker 中放置足够的相关代码。如您所见,控制器中的 console.log('test') 被记录到文档中,但 html 文档正文中未捕获的引用错误没有。

六个月后编辑:只是想指出问题及其解决方案仍然适用于使用 Typescript 的 Angular12 应用程序(尽管拦截控制台更改的脚本是加载到 "scripts": 我的生产配置数组,而不是项目中任何地方包含的 Typescript。)

一些改进:

  1. 为完整 dom 加载之前发生的错误创建一个消息队列数组。
  2. 在定义新控制台后使用window.addEventListener('error', callback)监听执行错误
  3. 等待 dom 加载以查询 logDiv。在定义之前将消息推送到消息队列中,然后在 dom 加载时检查该队列中的任何内容
let logDiv, messageQueue =[];

window.addEventListener('load', function(){
    // assign the log element
    logDiv = document.getElementById('logs');
    if(messageQueue.length){
        // print your preload errors
        messageQueue.forEach(([type,text])=>addToLogDiv(type,text))
    }
})

var addToLogDiv = function (type, text) {
  if(logDiv){
    var node = document.createElement('p')
    node.className = type
    var content = document.createTextNode(type + ': ' + text)
    node.appendChild(content)
    logDiv.appendChild(node)
  }else{
    // before logDiv defined store any errors
    messageQueue.push([type, text]) 
  } 
}

// define a new console
var console = (function (oldCons) {
  return {
    // same as before
  }
})(window.console)

//Then redefine the old console
window.console = console
// after new console created
window.addEventListener('error', function(e){
  console.log(e.message)
})

Demo in head