未捕获的类型错误:无法读取属性'长度'的未定义myTimer

Uncaught TypeError: Cannot read property 'length' of undefined myTimer

本文关键字:属性 长度 myTimer 未定义 读取 类型 错误      更新时间:2023-09-26

我有一个网站,它有一个表单,用户可以在其中输入电子邮件,提交后会发送到下一页。当我在这个页面上输入电子邮件,并分析控制台时,我看到以下异常:

Uncaught TypeError:无法读取未定义的myTimer@VM567 content.js:43(匿名函数(@VM567content.js:40 的属性"length">

当我点击这个时,我看到content.js为:

var gtmSnippet = document.createElement('script');
gtmSnippet.title = 'TMI-INJECTED-GTM-CONTAINER-SNIPPET';
gtmSnippet.id = 'tmigtmsnippet';
var gtmTrigger = document.createElement('div');
gtmTrigger.id = 'tmitriggerholder';
var THEID;   
function DB_setValue(name, value, callback) {
    var obj = {};
    obj[name] = value;
    console.log("Data Saved!");
    chrome.storage.local.set(obj, function() {
        if(callback) callback();
    });
}
    
chrome.runtime.sendMessage({greeting: "SnippetPlease"}, function(response) {
    THEID = response.farewell;
    if(response.farewell.length > 0){
        gtmSnippet.text = "//GTM CONTAINER INJECTION: 'n(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src='//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','" + response.farewell + "'); 'n//GTM CONTAINER INJECTION ENDS'n";
        
        // Get a value saved in a form.
        var theValue = THEID;
        // Check that there's some code there.
        if (!theValue) {
            return;
        }
        else{
            DB_setValue('theid',theValue,function(){});
        }
    }
});  
40 var interval = setInterval(function(){myTimer()}, 0.1);
41 function myTimer() {
42    if((document.body != null) && (THEID.length>0)){
43      // INJECT CONTAINER SNIPPET
44      document.body.appendChild(gtmSnippet);
45      
46      stopInterval();
47  }
}
function stopInterval() {
    clearInterval(interval);
}

我刚开始修改JavaScript,我不明白为什么会出现这个错误,

我该如何解决?

功能是同步的

变量THEID在异步函数中赋值:

chrome.runtime.sendMessage({greeting: "SnippetPlease"}, function(response) {
    THEID = response.farewell;
    ..

这意味着它将保持undefined,直到上面的回调函数接收到响应消息

如果您下面的时间间隔(,时间间隔太小(试图访问THEID的值,则不能保证已经收到响应并且已经设置了THEID的值。所以你遇到了undefined

var interval = setInterval(function(){myTimer()}, 0.1);
function myTimer() {
   // This function will be executed before the response is received
   // by chrome.runtime.sendMessage()
   if((document.body != null) && (THEID.length>0)){
     ...
     ...

解决此问题的一种方法

您可以考虑在响应回调中执行逻辑,而不是使用时间间隔进行检查。所以你的代码可能会变成:

chrome.runtime.sendMessage({greeting: "SnippetPlease"}, function(response) {
    THEID = response.farewell;
    ..
    ..
    // At this point of time, THEID is set from the response.
    if((document.body != null) && (THEID.length>0)){
        // INJECT CONTAINER SNIPPET
        document.body.appendChild(gtmSnippet);
    }
});

或其他方式

如果THEID未定义,则短路如下:

function myTimer() {
   // This function will be executed before the response is received
   // by chrome.runtime.sendMessage()
   if((document.body != null) && THEID && THEID.length>0)){
       ...
       ...

因此,您仍然可以使用您的时间间隔方法,只需进行少量修改。