Firefox扩展和HTML表单的完整文件路径?(Firefox extensions and full file paths from HTML form?)

其他开发 IT屋
问 题

I have built a Firefox extension using the Addon SDK that opens up a new tab with a HTML page from the extensions directory and attaches a content script to it:

function openHtmlLoadFormTab(htmlFileName, jsWorkerFileName) {
    tabs.open({
        url: data.url(htmlFileName),
        onReady: function(tab) {
            var tabWorker = tab.attach({
                contentScriptFile: [ data.url(jsJquery), data.url(jsWorkerFileName) ]
            });
        }
    });
}

I have an <input type="file"> in the HTML file and some code that handles the "submit" event in the JS file (these files are given by htmlFileName and jsWorkerFileName respectively)

Because of security reasons, I cannot access the full file path in JS with document.getElementById('uploadid').value. I only get the file's name.

However, since this is a Firefox extension, I'm wondering if there is anyway to override this restriction?

I have been looking into netscape.security.PrivilegeManager.enablePrivilege("UniversalFileRead") and mozFullPath but I haven't been able to get it to work. I believe it's deprecated anyway?

The other solution is to build an XUL-based UI and prompt for the file there somehow, but I would like to know for sure if there is anyway to get this to work in HTML.

First edit with small example code

I built a small sample extension to illustrate how I'm doing things.

lib/main.js

var self = require('self');
var tabs = require('tabs');
var data = self.data;
var jsLoadForm = "load-form.js", htmlLoadForm = "load-form.html";
var jsJquery = 'jquery-1.8.0.min.js';


exports.onUnload = function(reason) {};
exports.main = function(options, callbacks) {
    // TODO: remove this debugging line
    openHtmlLoadFormTab(htmlLoadForm, jsLoadForm);
};

function openHtmlLoadFormTab(htmlFileName, jsWorkerFileName) {
    tabs.open({
        url: data.url(htmlFileName),
        onReady: function(tab) {
            var tabWorker = tab.attach({
                contentScriptFile: [ data.url(jsJquery), data.url(jsWorkerFileName) ]
            });
        }
    });
}

data/load-form.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <title>Form</title>

        <script lang="text/javascript">
            function fileChanged(e) {
                // this is just the file name
                alert("html js: files[0].name: " + e.files[0].name);

                // mozFullPath is indeed empty, NOT undefined
                alert("html js: files[0].mozFullPath: " + e.files[0].mozFullPath);
            }
        </script>
    </head>

    <body>
        <form name="my-form" id="my-form" action="">
            <div>
                <label for="uploadid1" id="uploadlabel1">File (JS in HTML):</label>
                <input type="file" name="uploadid1" id="uploadid1" onchange="fileChanged(this)"/>
            </div>
            <div>
                <label for="uploadid2" id="uploadlabel2">File (JS in content script): </label>
                <input type="file" name="uploadid2" id="uploadid2" onchange="fileChangedInContentScript(this)"/>
            </div>
            <div>
                <label for="uploadid3" id="uploadlabel3">File (JS using jQuery in content script):</label>
                <input type="file" name="uploadid3" id="uploadid3" />
            </div>
        </form>
    </body>
</html>

data/load-form.js

$(document).ready(function() {
    $("#uploadid3").change(function(e) {
        // in jquery, e.files is null
        if(e.files != null)
            console.log("jquery: e.files is defined");
        else
            console.log("jquery: e.files is null");

        // this works, prints the file name though
        console.log("$('#uploadid3').val(): " + $("#uploadid3").val());
        // this is undefined
        console.log("$('#uploadid3').mozFullPath: " + $("#uploadid3").mozFullPath);
    });
});

// this handler never gets called
function fileChangedInContentScript(e) {
    alert("js content script: filechanged in content script called");
}

As you can see in main.js, I used jquery-1.8.0.min.js, downloaded from the jQuery website.

Note: I also tried these without jQuery included as a content script when I opened the tab in main.js, but no luck.

The conclusion is that mozFullPath is indeed empty when I access it from JS embedded in the HTML page and I cannot find a way to access mozFullPath from jQuery, nor can I find a way to add a onchange handler in load-form.html that's defined in load-form.js

Second edit with onchange handler in the load-form.js content-script

I added the following code to load-form.js to catch the onchange event. I also removed the jQuery content script from main.js

document.addEventListener("DOMContentLoaded", function() {
    try {
        document.getElementById("uploadid2").addEventListener('change', function(e) {
            console.log("addeventlistener worked!");    
            console.log("e: " + e);
            console.log("e.target: " + e.target);
            console.log("e.target.files: " + e.target.files);
            console.log("e.target.files[0].name: " + e.target.files[0].name);
            console.log("e.target.files[0].mozFullPath: " + e.target.files[0].mozFullPath);
        });

        console.log('added event listener')
    } catch(e) {
        console.log('adding event listener failed: ' + e);
    }
}, false);

This still outputs an empty string for mozFullPath:

info: added event listener
info: addeventlistener worked!
info: e: [object Event]
info: e.target: [object HTMLInputElement]
info: e.target.files: [object FileList]
info: e.target.files[0].name: test.sh
info: e.target.files[0].mozFullPath: 

Is there anyway to acquire the needed permissions? How can I get my hands on that full path? I need the full path so I can pass it to an application the extension launches. (There are workaround solutions where I can do without the full path, but they decrease the quality of the extension)

解决方案

fileInput.value property is meant to be accessible to web pages so it will only give you the file name, not the full path - web pages have no reason to know the full path on your machine. However, as a privileged extension you should be able to access the File.mozFullPath property. In this particular case you would do it like this:

var files = document.getElementById('uploadid').files;
if (files.length > 0)
{
  // Assuming that only one file can be selected
  // we care only about the first entry
  console.log(files[0].mozFullPath);
}

The big question of course is whether your code is allowed to access File.mozFullPath. I suspect that a content script in the Add-on SDK won't have the necessary privileges. The main extension code will have the privileges but getting to the input field from there is hard...

本文地址:IT屋 » Firefox extensions and full file paths from HTML form?

问 题

我使用Addon SDK构建了一个Firefox扩展,打开了一个新的标签,其中包含来自扩展目录的HTML页面,并将内容脚本附加到它:

 函数openHtmlLoadFormTab(htmlFileName,jsWorkerFileName){
tabs.open({
网址:data.url(htmlFileName)
onReady:功能(制表符){​​
变种tabWorker = tab.attach({
contentScriptFile:[data.url(jsJquery),data.url(jsWorkerFileName)]
});
}
});



我有一个< input type =“file HTML文件中的> 和处理JS文件中的“submit”事件的代码(这些文件由 htmlFileName 和 jsWorkerFileName )

由于安全原因,我无法使用的document.getElementById( 'UPLOADID')。值。我只是得到文件名。

然而,因为这是一个Firefox扩展,我想知道是否有重写这个限制吗?



我一直在寻找到 netscape.security.PrivilegeManager.enablePrivilege( “UniversalFileRead”)和 mozFullPath 但我一直没有能够得到它的工作。我认为它已被弃用吗?

另一个解决方案是建立一个基于XUL的用户界面,并在那里提示文件,但我想知道如果有无论如何,这将工作在HTML。

首先编辑小例子代码



我建立了一个小示例扩展来说明我是如何做的。

lib / main.js



  var self = require('self'); 
var tabs = require('tabs');
var data = self.data;
var jsLoadForm =“load-form.js”,htmlLoadForm =“load-form.html”;
var jsJquery ='jquery-1.8.0.min.js';


exports.onUnload = function(reason){};
exports.main = function(options,callbacks){
// TODO:移除此调试行
openHtmlLoadFormTab(htmlLoadForm,jsLoadForm);
};

功能openHtmlLoadFormTab(htmlFileName,jsWorkerFileName){
tabs.open({
网址:data.url(htmlFileName)
onReady:功能(制表符){​​
var tabWorker = tab.attach({
contentScriptFile:[data.url(jsJquery),data.url(jsWorkerFileName)]
});
}
}) ;

$ / code $ / pre
$ b

data / load-form.html $ /

 <!DOCTYPE HTML PUBLIC“ -  // W3C // DTD HTML 4.01 Transitional // EN”
“http: //www.w3.org/TR/html4/loose.dtd\">
< html>
< head>
< title>表格< /标题>

< script lang =“text / javascript”>
函数fileChanged(e){
//这只是文件名
alert(“html js:files [0] .name:”+ e.files [0] .name) ;

// mozFullPath确实是空的,NOT undefined
alert(“html js:files [0] .mozFullPath:”+ e.files [0] .mozFullPath);
}
< / script>
< / head>

< body>
< form name =“my-form”id =“my-form”action =“”>
< div>
< label for =“uploadid1”id =“uploadlabel1”>档案(JS in HTML):< / label>
< input type =“file”name =“uploadid1”id =“uploadid1”onchange =“fileChanged(this)”/>
< / div>
< div>
< label for =“uploadid2”id =“uploadlabel2”>文件(内容脚本中的JS):< / label>
< input type =“file”name =“uploadid2”id =“uploadid2”onchange =“fileChangedInContentScript(this)”/>
< / div>
< div>
< label for =“uploadid3”id =“uploadlabel3”>文件(在内容脚本中使用jQuery的JS):< / label>
< input type =“file”name =“uploadid3”id =“uploadid3”/>
< / div>
< / form>
< / body>
< / html> b


$ data $ load $ form $ $ $ class =“lang-js prettyprint-override”> $(document).ready(function(){
$(“#uploadid3”)。change(function(e){$ b $如果(e.files!= null)
console.log(“jquery:e.files is defined”);
else $ b(在jquery中,e.files为空
) $ b console.log(“jquery:e.files is null”);

//这个工作,打印文件名,但
console.log(“$('#uploadid3' ).val():“+ $(”#uploadid3“)。val());
//这是未定义的
console.log(”$('#uploadid3')。mozFullPath:“ + $(“#uploadid3”)。mozFullPath);
});
});
$ b $ //这个句柄永远不会被调用
函数fileChangedInContentScript(e){
alert(“js content script:filechanged in content script called”);





$你可以在main.js中看到,我使用jquery-1.8.0 .min.js,从jQuery网站下载。

注意:当我在main.js中打开选项卡时,我也尝试了这些没有包含作为内容脚本的jQuery,但是没有运气。

结论是,当我从嵌入在HTML页面的JS访问它时, mozFullPath 确实是空的我找不到从jQuery访问 mozFullPath 的方法,我也不能找到一种方法来添加 onchange 处理程序在load-form.js中定义的load-form.html

使用load-form.js内容脚本中的onchange处理程序进行第二次编辑

我将下面的代码添加到load-form.js来捕获onchange事件。
我也从main.js中删除了jQuery内容脚本


$ b
  document.addEventListener “DOMContentLoaded”,函数(){
尝试{
的document.getElementById( “uploadid2”)的addEventListener( '变',函数(E){
的console.log(“工作的addEventListener! “);
console.log(”e:“+ e);
console.log(”e.target:“+ e.target);
console.log(”e。 target.files:“+ e.target.files);
console.log(”e.target.files [0] .name:“+ e.target.files [0] .name);
console.log(“e.target.files [0] .mozFullPath:”+ e.target.files [0] .mozFullPath);
});

console.log ()添加事件监听器)
catch(e){
console.log('added event listener failed:'+ e);
}
},false);


这仍然为mozFullPath输出一个空字符串:



  info:添加事件监听器
info:addeventlistener工作!
info:e:[object Event]
info:e.target:[object HTMLInputElement]
info:e.target.files:[object FileList]
info:e。 target.files [0] .name:test.sh
info:e.target.files [0] .mozFullPath:


是否有获得所需的权限?我怎么能把我的手放在完整的路上?我需要完整的路径,所以我可以将它传递给扩展启动的应用程序。 (有解决方法,我可以做没有完整的路径,但他们降低了扩展的质量)解决方案

fileInput.value 属性意味着可以被网页访问,所以它只会给你文件名,而不是完整的路径 - 网页没有理由知道你的完整路径机。但是,作为特权扩展,您应该可以访问 File.mozFullPath 属性。在这种情况下,你可以这样做:

var files = document.getElementById(' 。UPLOADID“)的文件;
if(files.length> 0)
{
//假设只能选择一个文件
//我们只关心第一个入口
console .LOG(文件[0] .mozFullPath);





$ b

当然最大的问题是你的代码是否被允许访问 File.mozFullPath 。我怀疑附加SDK中的内容脚本将没有必要的权限。主要的扩展代码将有权限,但从输入字段是难... ...

本文地址:IT屋 » Firefox扩展和HTML表单的完整文件路径?