Firefox扩展/插件:从远程服务器(URL)读取文本文件

时间:2013-10-23 06:59:45

标签: javascript firefox firefox-addon mozilla

在浪费了我两天的时间来找出这个脚本出了什么问题之后,最后我决定问它。

我想做什么

我正在尝试从远程服务器读取文本文件。然后在我的Firefox Extension / 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中没有任何内容,将读取的数据传递到其他地方进行存储。

问题领域:

程序控制流程不是委托给本节

 onDataAvailable:

没有收到任何错误。

1 个答案:

答案 0 :(得分: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模块,如果需要较低级别的API,则应使用net/xhr

PS:如果您仍然对使用原始频道感兴趣,这里是我在Scratchpad中编码的最小示例(要运行,请为特权位置打开Scratchpad,例如{{1 }})。 您不应该从自己的实现中发出警告:about:newtab将旋转事件循环并导致可重入代码,在此上下文中不支持。

alert()