繁体   English   中英

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

[英]Firefox Extension/Addon : Reading a text file from remote server(URL)

在浪费我两天时间来找出此脚本出了什么问题之后,我终于决定去问它。

我要做什么

我正在尝试从远程服务器读取文本文件。 然后在加载Firefox扩展/插件时将所有文本文件更新存储到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中什么也没有得到, lineInputStream读取的数据传递到其他地方进行存储。

问题领域:

程序控制流程不属于本节

 onDataAvailable:

没有收到任何错误。

首先,似乎没有必要先将文件读取到磁盘上(除非它真的很大)。

我只是使用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();

如果要在非窗口(例如js代码模块或js组件)中使用XMLHttpRequest ,则需要首先初始化构造函数。 对于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,例如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);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM