Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to check tab load failed

I need do something on tabs updated, like check if the page load correct, and replace something inside the page. here is my code

// background.js

chrome.tabs.onUpdate.addListener(function(tabId, changeInfo, tab){
    try{
       chrome.tabs.executeScript(tabId, filename);
    } catch(e) {
       // 1. when I open a new tab
       // 1. Error during tabs.executeScript: Unknown error.
       // 2. when I request a url not arrive-able.
       // 2. Error during tabs.executeScript: Cannot access contents of url 
       //    "data:text/html,chromewebdata". Extension manifest must request 
       //    permission to access this host.

       // but I can't catch these errors, they just appers in background console.  
    }
});

I try to executeScript when it upload, but if the current tab is chrome://newtab or chrome error page, I can't do this, but I can't catch the error.

like image 755
guilin 桂林 Avatar asked Apr 19 '12 03:04

guilin 桂林


1 Answers

There's no direct way to catch these errors. However, I've just created a method to accomplish the goals:

  • Use chrome.tabs.onUpdated (with a d!).
    This event is fired twice, when the page is initializing ("loading"), and when the DOM has loaded ("complete").
  • Use chrome.tabs.executeScript(tabId, {file: fileName}, fn_callback);
    The second argument has to be an object, containing either "file", or "code". The third argument, a function, is always executed after finishing the script injection.

    Now, the real implementation:
    1. Execute the content script (using chrome.tabs.executeScript).
    2. In the injected content script, define an onMessage event.
    3. In the callback function of chrome.tabs.executeScript, follow these steps:
    4. Use var exec_error = setTimeout(onError, 100); to defer the execution of your onError method. Choose an appropriately small delay (100), and save a reference to this timeout in a variable, exec_error.
    5. Use chrome.tabs.sendMessage(tabId, func) to send a message to the tab.
    6. In callback function func, add this logic:
      • Validate the response (is the event not created by another part of the extension?)
      • clearTimeout(exec_error)
      • onSuccess()
    7. When an error occurs, the onMessage event as defined in 2. will not be injected. Hence, the tab will not respond as expected, and the time-out is not cleared. As a result, onError will be executed.
      Otherwise, the timeout is cleared, and onSuccess is executed.

Code (e.g. background script):

chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
    // This event fires twice: loading, and complete.
    // If we're loading, terminate function, and wait for "complete"
    if (changeInfo.status === 'loading') return;

    // On error and on success, this happens:
    function onError() {
        console.log('Error injecting the content script!');
    }
    function onSuccess() {
        console.log('Successfully injected content script!');
    }

    // Execute scripts
    chrome.tabs.executeScript(tabId, {
        file: 'test_access.js'
    }, function() {
        // This function always fires *after* the attempt to run the code
        var exec_error = setTimeout(onError, 100);
        chrome.tabs.sendMessage(tabId, 'Are you there?', function(yes_no) {
            if (yes_no === 'Yes') {
                clearTimeout(exec_error);
                onSuccess();
            }
        });
    });
});

test_access.js

chrome.extension.onMessage.addListener(function(req, sender, respond) {
   if (req === 'Are you there?') {
       respond('Yes');
   }
});
// Rest of your content script's logic, eg:
alert(location.href);
like image 83
Rob W Avatar answered Oct 05 '22 17:10

Rob W