最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Firefox WebExtensions, get local files content by path - Stack Overflow

programmeradmin2浏览0评论

I'm trying to write a small add-on for firefox using the WebExtensions structure.

This add-on should read a local file content by it's absolute path:
"/home/saba/desktop/test.txt"

manifest.json

{

    "manifest_version": 2,
    "name": "Test - load files",
    "version": "0.0.1",

    "description": "Test - load files",
    "permissions": [ "<all_urls>" ],

    "background": {
        "scripts": [ "main.js" ]
    }

}


Here what I tried so far (inside the main.js):



Using XMLHttpRequest

function readFileAjax(_path){

    var xhr = new XMLHttpRequest();

    xhr.onloadend = function(event) {
        console.log("onloadend", this);
    };

    xhr.overrideMimeType("text/plain");
    xhr.open("GET", "file:///"+_path);
    xhr.send();
}

readFileAjax("/home/saba/desktop/test.txt");

Failed. I can't figure out why it always return an empty response
(test.txt contains "test", the path is correct)

onloadend XMLHttpRequest { 
    onreadystatechange: null, 
    readyState: 4, 
    timeout: 0, 
    withCredentials: false, 
    upload: XMLHttpRequestUpload, 
    responseURL: "", 
    status: 0, 
    statusText: "", 
    responseType: "", 
    response: "" 
}




Using FileReader

function readFileFR(_path){

    var reader  = new FileReader();

    reader.addEventListener("loadend", function() {
       console.log("loadend", this.result)
    });

    reader.readAsText(file);  // file ???? 
}

readFileFR("/home/saba/desktop/test.txt");

but here I got stuck because of the file argument.
This method usually get along with an input type="file" tag which gives back a .files array. (but I only have a local path string)

I searched if was possible to create a new Blob or File var using an absolute local file path but seams like it's not possible.




Using WebExtensions API

I didn't find any clue form the documentation pages on how to do this.

Isn't there (maybe) some kind of WebExtensions API which makes this possible like in the SDK?




What am I doing wrong or missing?

..is it possible to get the content of a local file by it's absolute path with a WE Add-on?

I'm trying to write a small add-on for firefox using the WebExtensions structure.

This add-on should read a local file content by it's absolute path:
"/home/saba/desktop/test.txt"

manifest.json

{

    "manifest_version": 2,
    "name": "Test - load files",
    "version": "0.0.1",

    "description": "Test - load files",
    "permissions": [ "<all_urls>" ],

    "background": {
        "scripts": [ "main.js" ]
    }

}


Here what I tried so far (inside the main.js):



Using XMLHttpRequest

function readFileAjax(_path){

    var xhr = new XMLHttpRequest();

    xhr.onloadend = function(event) {
        console.log("onloadend", this);
    };

    xhr.overrideMimeType("text/plain");
    xhr.open("GET", "file:///"+_path);
    xhr.send();
}

readFileAjax("/home/saba/desktop/test.txt");

Failed. I can't figure out why it always return an empty response
(test.txt contains "test", the path is correct)

onloadend XMLHttpRequest { 
    onreadystatechange: null, 
    readyState: 4, 
    timeout: 0, 
    withCredentials: false, 
    upload: XMLHttpRequestUpload, 
    responseURL: "", 
    status: 0, 
    statusText: "", 
    responseType: "", 
    response: "" 
}




Using FileReader

function readFileFR(_path){

    var reader  = new FileReader();

    reader.addEventListener("loadend", function() {
       console.log("loadend", this.result)
    });

    reader.readAsText(file);  // file ???? 
}

readFileFR("/home/saba/desktop/test.txt");

but here I got stuck because of the file argument.
This method usually get along with an input type="file" tag which gives back a .files array. (but I only have a local path string)

I searched if was possible to create a new Blob or File var using an absolute local file path but seams like it's not possible.




Using WebExtensions API

I didn't find any clue form the documentation pages on how to do this.

Isn't there (maybe) some kind of WebExtensions API which makes this possible like in the SDK?
https://developer.mozilla.org/en-US/Add-ons/SDK/Low-Level_APIs/io_file
https://developer.mozilla.org/en-US/Add-ons/SDK/Low-Level_APIs/io_text-streams




What am I doing wrong or missing?

..is it possible to get the content of a local file by it's absolute path with a WE Add-on?

Share Improve this question edited Feb 8, 2017 at 11:41 Sabaz asked Feb 8, 2017 at 9:06 SabazSabaz 5,2722 gold badges20 silver badges26 bronze badges 5
  • 'file:///'+_path would result in file:////home/saba/desktop/test.txt - I think there's one too may / in there – Jaromanda X Commented Feb 8, 2017 at 9:08
  • I tried removing a / , same result unfortunately – Sabaz Commented Feb 8, 2017 at 9:12
  • Possibly using file:// URLs. – Daniel Herr Commented Feb 8, 2017 at 17:21
  • There is no WebExtension API for opening files, see also bugzilla.mozilla.org/show_bug.cgi?id=1246236. You can use <input type=file>. – evilpie Commented Feb 8, 2017 at 18:02
  • @evilpie ..so there's no solutions (atm) for what i'm trying to do. I'll keep using the SDK Add-on, even if they're going to deprecate it. – Sabaz Commented Feb 9, 2017 at 11:56
Add a comment  | 

2 Answers 2

Reset to default 17

I finally found the way to do this using the Fetch requests and FileReader APIs.

Here what I came up to:

function readFile(_path, _cb){

    fetch(_path, {mode:'same-origin'})   // <-- important

    .then(function(_res) {
        return _res.blob();
    })

    .then(function(_blob) {
        var reader = new FileReader();

        reader.addEventListener("loadend", function() {
            _cb(this.result);
        });

        reader.readAsText(_blob); 
    });
};

Using the example in my question this is how to use it:

readFile('file:///home/saba/desktop/test.txt', function(_res){

    console.log(_res); // <--  result (file content)

});

ES6 with promises

If you prefer to use Promises rather than callbacks:

let readFile = (_path) => {
    return new Promise((resolve, reject) => {
        fetch(_path, {mode:'same-origin'})
            .then(function(_res) {
                return _res.blob();
            })
            .then(function(_blob) {
                var reader = new FileReader();

                reader.addEventListener("loadend", function() {
                    resolve(this.result);
                });

                reader.readAsText(_blob);
            })
            .catch(error => {
                reject(error);
            });
    });
};

Using it:

readFile('file:///home/saba/desktop/test.txt')
    .then(_res => {
        console.log(_res); // <--  result (file content)
    })
    .catch(_error => {
        console.log(_error );
    });

This doesn't work, or at least not any longer taking the accepted answer into consideration.

Addon's run in a fake root meaning you can only ever access files which have been

  1. Shipped with your extension [1] using e.g. fetch() or
  2. Opened interactive (meaning initiated by the user using either the file picker or drag&drop) through the File() constructor [2]

Everything else will lead to a Security Error: Content at moz-extension://... may not load data from file:///... causing fetch() to throw the aforementioned TypeError: NetworkError when attempting to fetch resource.

[1] https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/web_accessible_resources
[2] https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Working_with_files#open_files_in_an_extension_using_a_file_picker

发布评论

评论列表(0)

  1. 暂无评论