Относительно остановки nsIRequest до его завершения и определения завершения nsIRequest (расширение firefox) - PullRequest
0 голосов
/ 11 февраля 2010

Спасибо всем заранее!

Я использую браузер xul: и подключаю к нему nsIWebProgressListener. Я пытаюсь сделать две вещи: 1. Определите, когда запрос завершен (когда документ полностью загружен всеми css / js / imgs). 2. Остановите запрос на завершение, особенно URL-адреса с файлами, которые выдают приглашение на загрузку.

Что касается моей первой проблемы, поскольку аргумент aStateFlags устанавливается с помощью (STATE_IS_ * | STATE_STOP) в nsIWebProgressListener.onStateChange () и вызывается несколько раз, невозможно определить, когда запрос выполнен на 100%, и нет больше изменений состояния. Как это достигается?

То, что я пытаюсь выполнить конкретно со второй проблемой, с которой я сталкиваюсь, - это прекращение запроса при обнаружении определенного значения заголовка типа содержимого. Например, если найден тип контента «application / pdf», если запрос прекращен, то приглашение на загрузку (которое, насколько я понимаю, не является частью nsIDownloadManager) никогда не отображается - это именно то поведение, которое я пытаюсь выполнить.

Вот код nsIWebProgressListener, с которым я сейчас работаю:

    //setup progress listener
    var progressListener = { 
        stateIsRequest:false,
        methodCalled:"",
        WebProgress:"",
        Request:"",
        Flag:"",
        Status:"",
        Location:"",
        CurSelfProgress:"",
        MaxSelfProgress:"",
        CurTotalProgress:"",
        MaxTotalProgress:"",
        Message:"",
        State:"",
        QueryInterface : function(aIID) {
            if(aIID.equals(Components.interfaces.nsIWebProgressListener) || aIID.equals(Components.interfaces.nsISupportsWeakReference) || aIID.equals(Components.interfaces.nsISupports)){
                return this;
            }
            else{
                throw Components.results.NS_NOINTERFACE;
            }
        },
        onStateChange : function(aWebProgress, aRequest, aFlag, aStatus) {
            this.methodCalled = "onStateChange";
            this.WebProgress = aWebProgress;
            this.Request = aRequest;
            this.Flag = aFlag;
            this.Status = aStatus;
            this.Location = "";
            this.CurSelfProgress = "";
            this.MaxSelfProgress = "";
            this.CurTotalProgress = "";
            this.MaxTotalProgress = "";
            this.Message = "";
            this.State = "";
            this.CaptureHeaders(aRequest);
        },

        onLocationChange : function(aWebProgress, aRequest, aLocation) {
            this.methodCalled = "onLocationChange";
            this.WebProgress = aWebProgress;
            this.Request = aRequest;
            this.Flag = "";
            this.Status = "";
            this.Location = aLocation;
            this.CurSelfProgress = "";
            this.MaxSelfProgress = "";
            this.CurTotalProgress = "";
            this.MaxTotalProgress = "";
            this.Message = "";
            this.State = "";
            this.CaptureHeaders(aRequest);
        },
        onProgressChange : function(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress){
            this.methodCalled = "onProgressChange";
            this.WebProgress = aWebProgress;
            this.Request = aRequest;
            this.Flag = "";
            this.Status = "";
            this.Location = "";
            this.CurSelfProgress = aCurSelfProgress;
            this.MaxSelfProgress = aMaxSelfProgress;
            this.CurTotalProgress = aCurTotalProgress;
            this.MaxTotalProgress = aMaxTotalProgress;
            this.Message = "";
            this.State = "";
            this.CaptureHeaders(aRequest);
        },
        onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage){
            this.methodCalled = "onStatusChange";
            this.WebProgress = aWebProgress;
            this.Request = aRequest;
            this.Flag = "";
            this.Status = aStatus;
            this.Location = "";
            this.CurSelfProgress = "";
            this.MaxSelfProgress = "";
            this.CurTotalProgress = "";
            this.MaxTotalProgress = "";
            this.Message = aMessage;
            this.State = "";
            this.CaptureHeaders(aRequest);
        },
        onSecurityChange : function(aWebProgress, aRequest, aState){
            this.methodCalled = "onSecurityChange";
            this.WebProgress = aWebProgress;
            this.Request = aRequest;
            this.Flag = "";
            this.Status = "";
            this.Location = "";
            this.CurSelfProgress = "";
            this.MaxSelfProgress = "";
            this.CurTotalProgress = "";
            this.MaxTotalProgress = "";
            this.Message = "";
            this.State = aState;
            this.CaptureHeaders(aRequest);
        },
        onLinkIconAvailable : function(a){},
        CaptureHeaders : function(ThisRequest){
            try{
                //specify response headers to get
                var ResponseHeaders = new Array();
                ResponseHeaders.push("status");
                ResponseHeaders.push("data");
                ResponseHeaders.push("server");
                ResponseHeaders.push("content-language");
                ResponseHeaders.push("content-encoding");
                ResponseHeaders.push("content-length");
                ResponseHeaders.push("expires");
                ResponseHeaders.push("cache-control");
                ResponseHeaders.push("keep-alive");
                ResponseHeaders.push("status");
                ResponseHeaders.push("connection");
                ResponseHeaders.push("content-type");
                ResponseHeaders.push("set-cookie");

                //specify request headers to get
                var RequestHeaders = new Array();
                RequestHeaders.push("host");
                RequestHeaders.push("user-agent");
                RequestHeaders.push("accept");
                RequestHeaders.push("accept-language");
                RequestHeaders.push("accept-encoding");
                RequestHeaders.push("accept-charset");
                RequestHeaders.push("keep-alive");
                RequestHeaders.push("connection");
                RequestHeaders.push("cookie");
                RequestHeaders.push("cache-control");

                //get browser
                var CurrentBrowser = document.getElementById("current_browser");
                //var CurrentURL = CurrentBrowser.current_url;
                //var CurrentURL = ThisRequest.nsIHttpChannel.originalURI.spec;

                if(ThisRequest.nsIHttpChannel != undefined){
                    var CurrentURL = ThisRequest.nsIHttpChannel.originalURI.spec;
                    //is this the first time headers were created for this browser?
                    if(CurrentBrowser.headers instanceof Object){
                        //have we collected headers for this url before
                        if(CurrentBrowser.headers[CurrentURL] instanceof Object){
                            //do nothing
                        }
                        else{
                            CurrentBrowser.headers[CurrentURL] = new Object();
                            CurrentBrowser.headers[CurrentURL].request = new Object();
                            CurrentBrowser.headers[CurrentURL].response = new Object()  
                        }
                    }
                    else{
                        CurrentBrowser.headers = new Object();
                        CurrentBrowser.headers[CurrentURL] = new Object();
                        CurrentBrowser.headers[CurrentURL].request = new Object();
                        CurrentBrowser.headers[CurrentURL].response = new Object()                  
                    }

                    //load up headers
                        //add response headers
                        for(i = 0; i < ResponseHeaders.length; i++){
                            try{
                                if(ResponseHeaders[i] == "status"){
                                    CurrentBrowser.headers[CurrentURL].response[ResponseHeaders[i]] = ThisRequest.nsIHttpChannel.responseStatus;                                    
                                }
                                else{
                                    CurrentBrowser.headers[CurrentURL].response[ResponseHeaders[i]] = ThisRequest.nsIHttpChannel.getResponseHeader(ResponseHeaders[i]);
                                }
                            }
                            catch(e){}
                        }

                        //add request headers
                        for(i = 0; i < RequestHeaders.length; i++){
                            try{
                                CurrentBrowser.headers[CurrentURL].request[RequestHeaders[i]] = ThisRequest.nsIHttpChannel.getRequestHeader(RequestHeaders[i]);
                            }
                            catch(e){}
                        }
                    //end load up headers

                    /*
                        Completed flag - STATE_IS_REQUEST:65552
                        Completed flag - STATE_IS_DOCUMENT:131088
                        Completed flag - STATE_IS_NETWORK:262160
                        Completed flag - STATE_IS_WINDOW:524304

                        //CurrentBrowser.webNavigation.nsIWebNavigation.stop(1);
                        //CurrentBrowser.webNavigation.nsIWebNavigation.stop(2);
                        //CurrentBrowser.webNavigation.nsIWebNavigation.stop(3);
                        //CurrentBrowser.stop();
                        //ThisRequest.cancel(2152398850);
                        //ThisRequest.cancel(Components.results.NS_OK);
                        //ThisRequest.suspend();
                    */

                    //setup nonload rules
                    if(CurrentBrowser.headers[CurrentURL].response["content-type"] == "application/zip"){
                        MyExtension.WriteToDebug("Cancelled Request: "+ CurrentURL);

                        //try multiple ways to terminate the request
                            if(ThisRequest.nsIHttpChannel.loadGroup.activeCount > 0){
                                ThisRequest.nsIHttpChannel.loadGroup.removeRequest(ThisRequest, ThisRequest, Components.results.NS_BINDING_ABORTED);
                            }

                            CurrentBrowser.webNavigation.nsIWebNavigation.stop(1);
                            CurrentBrowser.webNavigation.nsIWebNavigation.stop(2);
                            CurrentBrowser.webNavigation.nsIWebNavigation.stop(3);
                            CurrentBrowser.stop();
                            ThisRequest.cancel(Components.results.NS_OK);
                        //end try multiple ways to terminate the request

                        //after request is terminated execute onNONload
                        CurrentBrowser.OnNonLoad(CurrentURL);
                    }
                    //setup nonload rules
                    else if(CurrentBrowser.headers[CurrentURL].response["content-type"] == "application/pdf"){
                        MyExtension.WriteToDebug("Cancelled Request: "+ CurrentURL);

                        //try multiple ways to terminate the request
                            if(ThisRequest.nsIHttpChannel.loadGroup.activeCount > 0){
                                ThisRequest.nsIHttpChannel.loadGroup.removeRequest(ThisRequest, ThisRequest, Components.results.NS_BINDING_ABORTED);
                            }

                            CurrentBrowser.webNavigation.nsIWebNavigation.stop(1);
                            CurrentBrowser.webNavigation.nsIWebNavigation.stop(2);
                            CurrentBrowser.webNavigation.nsIWebNavigation.stop(3);
                            CurrentBrowser.stop();
                            ThisRequest.cancel(Components.results.NS_OK);
                        //end try multiple ways to terminate the request

                        //after request is terminated execute onNONload
                        CurrentBrowser.OnNonLoad(CurrentURL);
                    }
                    //determine if finished loading
                    else if(this.Flag == 65552 || this.Flag == 131088 || this.Flag == 262160 || this.Flag == 524304){
                        MyExtension.WriteToDebug("Request Completed!"); 
                        MyExtension.WriteToDebug("pending:"+ ThisRequest.isPending() +"<br/>name:"+ ThisRequest.name +"<br/>URL:"+ CurrentURL +"<br/>content-type:"+ CurrentBrowser.headers[CurrentURL].response["content-type"]+"<br/>status:"+ CurrentBrowser.headers[CurrentURL].response["status"]);
                        if(this.Flag == (Components.interfaces.nsIWebProgressListener.STATE_IS_REQUEST | Components.interfaces.nsIWebProgressListener.STATE_STOP)){
                            MyExtension.WriteToDebug("Completed flag - STATE_IS_REQUEST:"+ (Components.interfaces.nsIWebProgressListener.STATE_IS_REQUEST | Components.interfaces.nsIWebProgressListener.STATE_STOP)); 
                        }
                        if(this.Flag == (Components.interfaces.nsIWebProgressListener.STATE_IS_DOCUMENT | Components.interfaces.nsIWebProgressListener.STATE_STOP)){
                            MyExtension.WriteToDebug("Completed flag - STATE_IS_DOCUMENT:"+ (Components.interfaces.nsIWebProgressListener.STATE_IS_DOCUMENT | Components.interfaces.nsIWebProgressListener.STATE_STOP));
                        }
                        if(this.Flag == (Components.interfaces.nsIWebProgressListener.STATE_IS_NETWORK | Components.interfaces.nsIWebProgressListener.STATE_STOP)){
                            MyExtension.WriteToDebug("Completed flag - STATE_IS_NETWORK:"+ (Components.interfaces.nsIWebProgressListener.STATE_IS_NETWORK | Components.interfaces.nsIWebProgressListener.STATE_STOP));
                        }
                        if(this.Flag == (Components.interfaces.nsIWebProgressListener.STATE_IS_WINDOW | Components.interfaces.nsIWebProgressListener.STATE_STOP)){
                            MyExtension.WriteToDebug("Completed flag - STATE_IS_WINDOW:"+ (Components.interfaces.nsIWebProgressListener.STATE_IS_WINDOW | Components.interfaces.nsIWebProgressListener.STATE_STOP));
                        }


                        //MyExtension.WriteToDebug("methodCalled:"+ this.methodCalled);
                        //MyExtension.WriteToDebug("WebProgress:"+ this.WebProgress);
                        //MyExtension.WriteToDebug("Request:"+ this.Request);
                        MyExtension.WriteToDebug("Flag:"+ this.Flag);
                        //MyExtension.WriteToDebug("Status:"+ this.Status);
                        //MyExtension.WriteToDebug("Location:"+ this.Location);
                        //MyExtension.WriteToDebug("CurSelfProgress:"+ this.CurSelfProgress);
                        //MyExtension.WriteToDebug("MaxSelfProgress:"+ this.MaxSelfProgress);
                        //MyExtension.WriteToDebug("CurTotalProgress:"+ this.CurTotalProgress);
                        //MyExtension.WriteToDebug("MaxTotalProgress:"+ this.MaxTotalProgress);
                        //MyExtension.WriteToDebug("Message:"+ this.Message);
                        //MyExtension.WriteToDebug("State:"+ this.State);
                        MyExtension.WriteToDebug("Load group count:"+ ThisRequest.nsIHttpChannel.loadGroup.activeCount);
                        MyExtension.WriteToDebug("WebProgress.isLoadingDocument:"+ this.WebProgress.isLoadingDocument);
                        MyExtension.WriteToDebug("WebProgress.DOMWindow:"+ this.WebProgress.DOMWindow);
                        //execute non load
                        //CurrentBrowser.OnNonLoad(CurrentURL);
                    }
                }
            }
            catch(e){
                MyExtension.WriteToDebug("Error Name:"+ e.name +" Message:"+ e.message);
            }
        }
    };

    //add progress listener
    ThisBrowser.addProgressListener(progressListener);
//end setup progress listener

https://developer.mozilla.org/en/nsIWebProgressListener

Ответы [ 2 ]

1 голос
/ 22 октября 2012

Для тех, у кого есть этот вопрос в будущем ...

Это хороший пример для начала: https://developer.mozilla.org/en-US/docs/Code_snippets/Progress_Listeners#Example

Пример очистки IMHO, который заботится о добавлении / удалении ProgressListeners при открытии и закрытии вкладок (предотвращает утечки памяти), доступен здесь: http://mdn.beonex.com/en/XUL_School/Intercepting_Page_Loads

Только при использовании STATE_IS_DOCUMENT и STATE_STOP вы получите один результат на запрос URI: для последней загруженной страницы.

Вам потребуется получить aLocation, если вы хотите проверить URL-адрес, вам нужно отменить aLocation.spec и aRequest, чтобы можно было выдать aRequest.cancel (NS_BINDING_ABORTED). Вы можете просто перейти с загружаемой страницы, используя aWebProgress.DOMWindow, добавив XUL и перезагрузив его.

HTH,

Эрик

1 голос
/ 11 февраля 2010

У меня сейчас довольно ленивое настроение, поэтому я не могу сказать, что я провел много исследований ...

Вопрос 1:
Почему бы просто не подключиться к contentDocument для события загрузки. Если contentDocument не раскрывается раньше, используйте следующий код, чтобы узнать, доступен ли он тогда:

Listener.prototype.onStateChange = function(webProgress, request, stateFlags, status) {
    if(stateFlags & Components.interfaces.nsIWebProgressListener.STATE_STOP && stateFlags & Components.interfaces.nsIWebProgressListener.STATE_IS_NETWORK) {
        // Should be ready now.... please?
    }
};

Вопрос 2:
Я не уверен, что вы пытаетесь сделать с этим и как это относится к браузеру xul: .

...