2013-10-23 73 views
0

在浪費了我兩天的時間來找出這個腳本出了什麼問題之後,我終於決定問這個問題。Firefox擴展/插件:從遠程服務器(URL)讀取文本文件

我所試圖做的

我想讀從遠程服務器上的文本文件。然後將所有文本文件更新存儲到我的Firefox擴展/ Addon加載時的SQLITE數據庫中。

我試過

var updatereader = { 

    start: function() { 
    //alert('reading update'); 
     var fURL = null; 
     var ioService = null; 
     var fURI = null; 
     var httpChannel = null; 

     fURL = "http://www.example.com/addon/mlist.txt"; 
     ioService = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService); 
     fURI = ioService.newURI(fURL, null, null); 
     httpChannel = ioService.newChannelFromURI(fURI).QueryInterface(Components.interfaces.nsIHttpChannel); 
     httpChannel.asyncOpen(updatereader.StreamReader, null); 
    }, 

    onUpdateCompleted: function() { 

    }, 

    StreamReader: 
    { 
     fOutputStream: null, 
     fPointer: null, 
     tempFile: "mlist.txt", 

     onStartRequest: function (aRequest, aContext) { 
     //alert('onStart'); 
      updatereader.StreamReader.fOutputStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream); 
      updatereader.StreamReader.fPointer = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsIFile); 
      updatereader.StreamReader.fPointer.append(updatereader.StreamReader.tempFile); 
      updatereader.StreamReader.fOutputStream.init(updatereader.StreamReader.fPointer, 0x02 | 0x20 | 0x08, 0644, 0); 
     }, 

     onDataAvailable: function (aRequest, aContext, aInputStream, aOffset, aCount) { 
     //control flow is not entering here - may be here is somehting missing 
      var sStream = null; 
      var tempBuffer = null; 
      sStream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream); 
      sStream.init(aInputStream); 
      tempBuffer = sStream.read(aCount); 
      updatereader.StreamReader.fOutputStream.write(tempBuffer, aCount); 
     }, 

     onStopRequest: function (aRequest, aContext, aStatusCode) { 
     //alert('onStop'); 
      var currentDate = new Date(); 
      if (aStatusCode == 0) { 
       fileInputStream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream); 

       updatereader.StreamReader.fOutputStream.close(); 
       fileInputStream.init(updatereader.StreamReader.fPointer, 0x01, 0, 0); 
       lineInputStream = fileInputStream.QueryInterface(Components.interfaces.nsILineInputStream); 

      //pass data to somewhere 
       var dbH = new dbstore(); 
       dbH.updateData(lineInputStream); 

       lineInputStream.close(); 

       updatereader.StreamReader.fPointer.remove(false); 


       updatereader.onUpdateCompleted(); 
      } else { 

      } 
     } 
    } 
} 

問題:

獲得在lineInputStream事情在讀取數據傳送到別的地方存放。

的問題區域:

程序控制流不entring本節

onDataAvailable: 

沒有得到任何錯誤。

回答

0

首先,似乎沒有必要先將文件讀取到磁盤(除非它真的很大)。

我只是使用XMLHttpRequest來獲取文件,該文件從特權上下文(例如附加代碼,但不是網站)運行時可以訪問任何和每個有效的URI。 XMLHttpRequest幾乎可以簡化所有內容,例如沒有更多onDataAvailable,(通常)沒有更多的手動文本轉換等。 另外,在傳輸過程中不需要碰到磁盤。

代碼會是這個樣子:

var req = new XMLHttpRequest(); 
req.open("GET", "http://www.example.com/addon/mlist.txt"); // file:/// would work too, BTW 
req.overrideMimeType("text/plain"); 
req.addEventListener("load", function() { 
    // Do something with req.responseText 
}, false); 
req.addEventListener("error", function() { 
    // Handle error 
}, false); 
req.send(); 

如果你想在一個非窗口,例如使用XMLHttpRequest js代碼模塊或者js組件,那麼你需要先初始化一個構造函數。這不是Windows所必需的,包括XUL窗口和XUL覆蓋。

// Add XMLHttpRequest constructor, if not already present 
if (!('XMLHttpRequest' in this)) { 
    this.XMLHttpRequest = Components.Constructor("@mozilla.org/xmlextras/xmlhttprequest;1", "nsIXMLHttpRequest"); 
} 

SDK用戶應當使用request模塊,或net/xhr如果需要較低級別的API。

PS:如果你仍然有興趣使用渠道,這裏是一個小例子,我在便籤編寫了(運行,打開一個便籤了一個優越的位置,如about:newtab)。 您不應該從您自己的實現中發出警報:alert()將旋轉事件循環並導致重入代碼,這在此上下文中不受支持。

var { 
    classes: Cc, 
    interfaces: Ci, 
    results: Cr, 
    utils: Cu 
} = Components; 

Cu.import("resource://gre/modules/XPCOMUtils.jsm") 
Cu.import("resource://gre/modules/Services.jsm"); 

var ConverterStream = Components.Constructor(
    "@mozilla.org/intl/converter-input-stream;1", 
    "nsIConverterInputStream", 
    "init"); 
var RC = Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER; 

function Listener() { 
    this.content = ""; 
} 
Listener.prototype = { 
    QueryInterface: XPCOMUtils.generateQI([Ci.nsIStreamListener]), 
    onStartRequest: function(req, ctx) { 
     console.log("start"); 
    }, 
    onDataAvailable: function(req, ctx, stream, offset, count) { 
     console.log("data", count); 
     try { 
      var cs = new ConverterStream(stream, null /* utf-8 */, 4096, RC); 
      try { 
       var str = {}; 
       while (cs.readString(4096, str)) { 
        this.content += str.value; 
       } 
      } 
      finally { 
       cs.close(); 
      } 
     } 
     catch (ex) { 
      console.error("data", ex.message, ex); 
     } 
    }, 
    onStopRequest: function(req, ctx, status) { 
     console.log("stop", status, 
        this.content.substr(0, 20), this.content.length); 
    } 
}; 

var uri = Services.io.newURI("http://example.org", null, null); 
Services.io.newChannelFromURI(uri).asyncOpen(new Listener(), null); 
+0

@namier感謝您的重播,我非常新,'req.responseText'什麼也沒有返回。 'req.send()的用途是什麼?'我想跟隨你的第一部分代碼。所以你可以讓它更容易理解。像我們傳遞URL時返回文本的函數一樣 –

+0

Web上有大量資源討論XMLHttpRequest的用法。畢竟,它是現代網絡最重要的組成部分之一。這是一個開始:https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest – nmaier