3

在我的扩展中,我需要使用部分 URL 被一些标记替换的书签。当用户打开此类书签时,扩展程序应将此标记替换为某个值并打开新位置。为了实现这一点,我使用了 nsIWebProgressListener,如下所示:

bookmarksResolver: {
    onLocationChange: function(aWebProgress, aRequest, aLocation, aFlags) {
        if (aLocation) {
            try {
                // Replace markers
                var resolvedLocation = resolveReferences(location);
                if (resolvedLocation != location) { // Open new location if markers were found and replaced
                    aWebProgress.DOMWindow.location.replace(resolvedLocation);
                }
            }
            catch(ex) {
                   //Logging error
            }
        }
    },

    /* Stubs for other listeners */
    onStateChange: function(a, b, c, d) {},
    onProgressChange: function(a, b, c, d, e, f) {},
    onStatusChange: function(a, b, c, d) {},
    onSecurityChange: function(a, b, c) {},

    QueryInterface: function (aIID) {
        if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
                aIID.equals(Components.interfaces.nsIWebProgressListener2) ||
                aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
                aIID.equals(Components.interfaces.nsISupports)) {
            return this;
        }
        else {
            throw Components.results.NS_NOINTERFACE;
        }
    }
},

问题是当我尝试替换 URL 中的标记时,例如https://[marker].site.com显示一个奇怪的错误页面(说 netError.xhtml 上存在语法错误),然后打开带有替换标记的 url,但地址栏一直显示https://[marker].site.comURL。

问题 #1:我在这里正确使用 onLocationChange 吗?也许,应该使用另一种方法?

问题 #2:我该怎么做才能防止此错误发生?


UPD:使用 onStateChange 而不是 onLocationChange 并使用标志 STATE_TRANSFERRING | STATE_IS_DOCUMENT 因为捕获标志 STATE_START | STATE_IS_DOCUMENT 在重定向之前导致严重的 UI 挂起。我还提出了请求取消方法调用。现在看起来像这样:

bookmarksResolver: {
    onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus) {
        var nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
        if (aStateFlags & nsIWebProgressListener.STATE_TRANSFERRING
                    && aStateFlags & nsIWebProgressListener.STATE_IS_REQUEST) {
            try {
                var location = aWebProgress.DOMWindow.location.href;
                var resolvedLocation = resolveReferences(location);
                if (resolvedLocation != location) {
                    aRequest.cancel(Components.results.NS_BINDING_REDIRECTED);
                    aWebProgress.DOMWindow.location.href = resolvedLocation;
                    logger.info('Old URL: [' + location + ']');
                    logger.info('Redirected to: [' + resolvedLocation + ']');
                }
            }
            catch(ex) {
                    //Logging error
            }
        }
    },

    /* Stubs for other listeners */
    onLocationChange: function(a, b, c, d) {},
    onProgressChange: function(a, b, c, d, e, f) {},
    onStatusChange: function(a, b, c, d) {},
    onSecurityChange: function(a, b, c) {},

    QueryInterface: function (aIID) {
        if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
                aIID.equals(Components.interfaces.nsIWebProgressListener2) ||
                aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
                aIID.equals(Components.interfaces.nsISupports)) {
            return this;
        }
        else {
            throw Components.results.NS_NOINTERFACE;
        }
    }
},

除 RSS 页面外,一切正常。旧位置和“重定向到”的日志条目显示标记已被替换并且新 URL 是正确的。但是它们会一遍又一遍地重新加载,因为实际的 URL(我从中得到aWebProgress.DOMWindow.location.href)由于某种原因没有更改,并且会一次又一次地执行替换。加载 RSS URL 有什么不同以及如何解决这个问题?

4

1 回答 1

2

Q1:我更喜欢onStateChange

Q2:也许aRequest.cancel(Components.results.NS_BINDING_REDIRECTED)会和平结束最初的请求。

于 2012-10-30T17:41:02.390 回答