1

Addon SDK を使用して Firefox 拡張機能を作成しました。これは、拡張機能ディレクトリから HTML ページを含む新しいタブを開き、それにコンテンツ スクリプトを添付します。

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

HTML ファイルにが<input type="file">あり、JS ファイルに「送信」イベントを処理するコードがいくつかあります (これらのファイルはそれぞれ および で指定されhtmlFileNameますjsWorkerFileName) 。

セキュリティ上の理由から、JS の完全なファイル パスにdocument.getElementById('uploadid').value. 私はファイルの名前だけを取得します。

ただし、これは Firefox の拡張機能であるため、この制限を無効にする方法はあるのでしょうか?

私は調べていましたがnetscape.security.PrivilegeManager.enablePrivilege("UniversalFileRead")mozFullPathそれを機能させることができませんでした。とにかく非推奨だと思いますか?

もう 1 つの解決策は、XUL ベースの UI を作成し、そこにあるファイルのプロンプトを表示することですが、これを 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: 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");
}

main.js でわかるように、jQuery Web サイトからダウンロードした jquery-1.8.0.min.js を使用しました。

注: main.js でタブを開いたときに jQuery をコンテンツ スクリプトとして含めずにこれらも試しましたが、うまくいきませんでした。

結論はmozFullPath、HTML ページに埋め込まれた JS からアクセスすると実際には空であり、jQuery からアクセスする方法を見つけることができず、load-form.html で定義されている load-form.html にハンドラーmozFullPathを追加する方法を見つけることもできません。 onchangeform.js

load-form.js content-script の onchange ハンドラーを使用した 2 番目の編集

onchange イベントをキャッチするために、次のコードを load-form.js に追加しました。また、main.js から jQuery コンテンツ スクリプトを削除しました。

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);

これはまだ 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: 

とにかく必要な権限を取得する方法はありますか? どうすればその完全なパスを手に入れることができますか? 拡張機能が起動するアプリケーションに渡すことができるように、完全なパスが必要です。(フルパスなしでできる回避策がありますが、拡張機能の品質が低下します)

4

1 に答える 1

1

fileInput.valueプロパティは Web ページからアクセスできるようになっているため、フル パスではなくファイル名のみが表示されます。Web ページは、マシン上のフル パスを知る必要はありません。File.mozFullPathただし、特権拡張機能として、プロパティにアクセスできる必要があります。この特定のケースでは、次のようにします。

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);
}

もちろん、大きな問題は、あなたのコードが へのアクセスを許可されているかどうかですFile.mozFullPath。アドオン SDK のコンテンツ スクリプトに必要な権限がないのではないかと思います。メインの拡張コードには権限がありますが、そこから入力フィールドに到達するのは難しいです...

于 2012-08-27T18:48:42.513 に答える