在firefox扩展中读取本地json文件

时间:2014-03-08 11:10:20

标签: javascript json firefox-addon

我正在编写一个firefox扩展,并希望该功能上传本地json文件并读取此文件以执行进一步的操作。简单来说,这个json文件包含一个url列表,如果它们出现在网页上,插件读取时将有助于突出显示这些URL。

正如建议here,我正在尝试使用扩展程序面板中的标记然后尝试使用FileReader来访问文件的内容,但遗憾的是我无法执行此操作。

代码如下:

<input type="file" name="uploadFile" id="files"/>

 function handleFileSelect(evt){
 /* some code */
    }

 document.getElementById('files').addEventListener('change', handleFileSelect,false);

在javascript代码中,收到的'evt'参数为空{}。

问题:

  1. 是否有其他替代/更好的方法来读取json文件 在Firefox扩展程序中。

  2. 为什么“evt”参数在给定的情况下为空。

4 个答案:

答案 0 :(得分:2)

如果你真的想使用FileReader,这是一个有效的例子:fiddle。浏览并选择一个包含json内容的文件,它将解析它并将全局json var设置为它。

它设置了多个文件选择,您可以通过删除multiple属性并调整脚本以便不循环来改变它。

或将其粘贴到html文件中以进行测试

<input type="file" id="files" name="files[]" multiple />
<output id="list"></output>
var json;

function handleFileSelect(evt) {
    var files = evt.target.files; // FileList object

    // files is a FileList of File objects. List some properties.

}

document.getElementById('files').addEventListener('change', handleFileSelect, false);

function handleFileSelect(evt) {
    var files = evt.target.files; // FileList object

    // files is a FileList of File objects. List some properties.
    var output = [];
    for (var i = 0, f; f = files[i]; i++) {
        var reader = new FileReader();

        // Closure to capture the file information.
        reader.onload = (function (theFile) {
            return function (e) {
                console.log('e readAsText = ', e);
                console.log('e readAsText target = ', e.target);
                try {
                    json = JSON.parse(e.target.result);
                    alert('json global var has been set to parsed json of this file here it is unevaled = \n' + JSON.stringify(json));
                } catch (ex) {
                    alert('ex when trying to parse json = ' + ex);
                }
            }
        })(f);
        reader.readAsText(f);
    }

}

答案 1 :(得分:2)

如果喜欢@Noitidart,你会发现同步读写很难,这里是异步读写的代码:

/*start - example usage*/
var file = FileUtils.getFile("Desk", ["rawr.txt"]); //this gets file on desktop named 'rawr.txt'
//can also go: var file = FileUtils.File('C:\\Documents and Settings\\My User Name\\Desktop\\rawr.txt');

overwriteFile(file, 'blah blah blah', function (status) {
   alert('overwrite status == ' + Components.isSuccessCode(status));
});

readFile(file, function (dataReadFromFile, status) {
   alert('file read status == ' + Components.isSuccessCode(status));
   alert('contents of file is:\n' + dataReadFromFile);
});
/*end - example usage*/





Components.utils.import("resource://gre/modules/FileUtils.jsm");
Components.utils.import("resource://gre/modules/NetUtil.jsm");
function overwriteFile(nsiFile, data, callback) {
   //data is data you want to write to file
   //if file doesnt exist it is created
   var ostream = FileUtils.openSafeFileOutputStream(file)
   var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
   converter.charset = "UTF-8";
   var istream = converter.convertToInputStream(data);
   // The last argument (the callback) is optional.
   NetUtil.asyncCopy(istream, ostream, function (status) {
      if (!Components.isSuccessCode(status)) {
         // Handle error!
         alert('error on write isSuccessCode = ' + status);
         return;
      }
      // Data has been written to the file.
      callback(status)
   });
}

function readFile(nsiFile, callback) {
   //you must pass a callback like function(dataReadFromFile, status) { }
   //then within the callback you can work with the contents of the file, it is held in dataReadFromFile
   //callback gets passed the data as string
   NetUtil.asyncFetch(file, function (inputStream, status) {
      //this function is callback that runs on completion of data reading
      if (!Components.isSuccessCode(status)) {
         alert('error on file read isSuccessCode = ' + status);
         return;
      }
      var data = NetUtil.readInputStreamToString(inputStream, inputStream.available());
      callback(data, status);
   });
}

答案 2 :(得分:1)

您正在制作Firefox扩展程序,以便您可以访问更强大的内容,例如OSFile.jsm

我更喜欢。

您可以使用nsIJSON - decodeFromStream

你也可以使用FileUtils.jsm来读取文件,这是一个深刻的例子:https://developer.mozilla.org/en-US/Add-ons/Code_snippets/File_I_O#Writing_to_a_file

如果您希望用户选择文件,您应该使用nsIFilePicker。这里有详细的例子:https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsIFilePicker?redirectlocale=en-US&redirectslug=nsIFilePicker#Example

答案 3 :(得分:0)

这是一个js模块:

let EXPORTED_SYMBOLS = [
    'importJSON',
    'exportJSON',
    'readUTF8File',
    'writeUTF8File',
    'nsFile'
];


const Cc = Components.classes;
const Ci = Components.interfaces;

//unused here, only exported
let nsFile = Components.Constructor("@mozilla.org/file/local;1", Ci.nsILocalFile, "initWithPath");


function exportJSON(obj, file, indent){
    if(typeof indent == 'undefined') indent = 0;
    let s = JSON.stringify(obj, null, indent);
    writeUTF8File(file, s, true);
}

function importJSON(file){
    let s = readUTF8File(file);
    return JSON.parse(s);
}


function readUTF8File(file){
    var aFile;
    if(typeof file === 'string'){
        aFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
        aFile.initWithPath(file);
        if (!aFile.exists() || !aFile.isFile()){
            aFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0x1FF);
        }
    } else {
        //var aFile.initWithFile(file);
        aFile = file;
    }
    if (!aFile.exists() || !aFile.isFile()){
        return null;
    }       
    var fstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
    var cstream = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(Ci.nsIConverterInputStream);
    fstream.init(aFile, -1, 0, 0);
    cstream.init(fstream, "UTF-8", 0, 0);
    var str = {};
    cstream.readString(-1, str); // read the whole file and put it in str.value
    var data = str.value;
    cstream.close(); //this also closes fstream?
    fstream.close(); //needed or not?
    return data;
};

function writeUTF8File(file, data, overwrite){
    if(typeof file === 'string'){
        var aFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
        aFile.initWithPath(file);
        if (!aFile.exists() || !aFile.isFile()){
            aFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0x1FF);
        }
    } else {
        //var aFile.initWithFile(file);
        var aFile = file;
    }
    var foStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
    var converter = Cc["@mozilla.org/intl/converter-output-stream;1"].createInstance(Ci.nsIConverterOutputStream);

    if(overwrite){
        // write|create|truncate
        foStream.init(aFile, 0x02 | 0x08 | 0x20, 0x1B6, 0); 
    }else{
        // write|create|append
        foStream.init(aFile, 0x02 | 0x08 | 0x10, 0x1B6, 0);
    }
    /*
    //write|create : will write to file from start (like taping over a casette!)
    //foStream.init(aFile, 0x02 | 0x08, 0666, 0);*/
    converter.init(foStream, "UTF-8", 0, 0);
    converter.writeString(data);
    converter.close(); // this closes foStream?
    foStream.close();//not needed?
};

用法演示:

var rwjson={};
Components.utils.import('file:///D:/_VB%20Progs/%5BFirefox%5D/%5BRepository%5D/JSON%20Read-Write%20to%20UTF-8%20File/rwjson.jsm', rwjson);


rwjson.exportJSON( {cool:'me'} , 'c:\\test1.json', 4); //indent=4 spaces
let o = rwjson.importJSON('c:\\test1.json'); //o.cool

//extra stuff
rwjson.writeUTF8File('c:\\cool.txt', 'some text...\n', /*overwrite*/ false);
rwjson.readUTF8File('c:\\cool.txt');

//totally unrelated!
var f = rwjson.nsFile('C:\\cool.txt');
f instanceof Ci.nsILocalFile //true
f instanceof Ci.nsIFile //true
f.exists();
f.isFile();
f.isDirectory();
//f.launch();
//f.reveal();