매우 늦은 답변에 대해 죄송합니다.
질문을 올바르게 이해하면 Firefox에서 실행되는 P.O.S 응용 프로그램이 HTTP를 통해 일종의 로컬 웹 서버와 통신합니다. 응용 프로그램의 클라이언트 측 JavaScript는 브라우저의 PC의 로컬 파일 시스템에서 파일을 쓰고 &을 읽을 수 있어야합니다.
맞으면 다음과 같이 할 수 있습니다. 가장 간단한 종류의 "부트 스트랩 드 (bootstrapped)"(또는 "재시작없는") 애드온 인 파이어 폭스 애드온을 만들어야합니다. (XML 파일이 Firefrox로 부가 기능을 설명
addon을 빌드하려면 두 파일을 파일 확장자가 .xpi
인 ZIP 파일의 최상위 폴더 (폴더 없음!)에두기 만하면됩니다. 애드온을 설치하려면 about:addons
으로 이동 한 다음 도구 메뉴에서 Install from file
을 클릭하고 XPI를 찾아서 연 다음 잠시 후 Install
을 선택하십시오. install.rdf
에서
는 다음과 같이 넣어 :
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>youraddon[email protected]</em:id>
<em:type>2</em:type>
<em:name>Name of your addon</em:name>
<em:version>1.0</em:version>
<em:bootstrap>true</em:bootstrap>
<em:description>Describe your addon.</em:description>
<em:creator>Your name</em:creator>
<!-- Firefox Desktop -->
<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>4.0.*</em:minVersion>
<em:maxVersion>29.0.*</em:maxVersion>
</Description>
</em:targetApplication>
</Description>
</RDF>
당신은
bootstrap.js
에 두 개의 필수 자바 스크립트 함수를 구현해야
:
startup()
을 -라고 당신이 애드온을 설치할 때 , 그리고 브라우저가 시작될 때.
shutdown()
- 애드온을 제거하고 브라우저가 종료 될 때 호출됩니다.
나머지 '특권'코드는 startup()
으로 전화해야합니다. 위생을 위해서는 install()
및 uninstall()
기능을 구현할 수 있습니다.bootstrap.js
에 다음 코드를 구현하여
시작 : 기본적으로
const Cc = Components.classes;
const Ci = Components.interfaces;
let consoleService = Cc["@mozilla.org/consoleservice;1"]
.getService(Ci.nsIConsoleService);
let wm = Cc["@mozilla.org/appshell/window-mediator;1"]
.getService(Ci.nsIWindowMediator);
function LOG(msg) {
consoleService.logStringMessage("EXTENSION: "+msg);
}
function startup() {
try {
LOG("starting up...");
let windows = wm.getEnumerator("navigator:browser");
while (windows.hasMoreElements()) {
let chromeWindow = windows.getNext().QueryInterface(Ci.nsIDOMWindow);
WindowListener.setupBrowserUI(chromeWindow);
}
wm.addListener(WindowListener);
LOG("done startup.");
} catch (e) {
LOG("error starting up: "+e);
}
}
function shutdown() {
try {
LOG("shutting down...");
let windows = wm.getEnumerator("navigator:browser");
while (windows.hasMoreElements()) {
let chromeWindow = windows.getNext().QueryInterface(Ci.nsIDOMWindow);
WindowListener.tearDownBrowserUI(chromeWindow);
}
wm.addListener(WindowListener);
LOG("done shutdown.");
} catch (e) {
LOG("error shutting down: "+e);
}
}
, 웹 브라우저의 각 전류 & 미래의 창에 대한 WindowListener.setupBrowserUI()
를 호출합니다. 다음과 같이 WindowListener
정의됩니다 :
OpenWindow
이벤트에 대한 이벤트 리스너를 설정하고 차례로 각 ChromeWindow의
TabBrowser
에서
load
이벤트에 대한 이벤트 리스너를 설치
var WindowListener = {
setupBrowserUI: function(chromeWindow) {
chromeWindow.gBrowser.addEventListener('load', my_load_handler, true);
},
tearDownBrowserUI: function(chromeWindow) {
chromeWindow.gBrowser.removeEventListener('load', my_load_handler, true);
},
onOpenWindow: function(xulWindow) {
let chromeWindow = xulWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow);
chromeWindow.addEventListener("load", function listener() {
chromeWindow.removeEventListener("load", listener, false);
var domDocument = chromeWindow.document.documentElement;
var windowType = domDocument.getAttribute("windowtype");
if (windowType == "navigator:browser")
WindowListener.setupBrowserUI(chromeWindow);
}, false);
},
onCloseWindow: function(chromeWindow) { },
onWindowTitleChange: function(chromeWindow, newTitle) { }
};
. load
이벤트 핸들러는 다음과 같이 정의된다 :
window.location.href
을 확인하여 (올바른 페이지를 대상으로 다음과 같이 정의되어 자신의
window
객체에
install_my_privileged_methods
호출
var my_load_handler = function (evt) {
try {
var browserEnumerator = wm.getEnumerator("navigator:browser");
while (browserEnumerator.hasMoreElements()) {
var browserWin = browserEnumerator.getNext();
var tabbrowser = browserWin.gBrowser;
var numTabs = tabbrowser.browsers.length;
for (var index = 0; index < numTabs; index++) {
var currentBrowser = tabbrowser.getBrowserAtIndex(index);
var domWindow = currentBrowser.contentWindow.wrappedJSObject;
// identify your target page(s)...
if (domWindow.location.href == 'http://yourserver/yourpage') {
// install the privileged methods (if not already there)
if (!domWindow.hasOwnProperty('__my_priv_members__') {
install_my_privileged_methods(browserWin, domWindow);
}
}
}
}
} catch (e) {
LOG(e);
}
}
:
이
function install_my_privileged_methods(chromeWindow, domWindow) {
install_privileged_method(chromeWindow, domWindow, 'WriteFile',
function(priv) {
return function(File, Text, cb) {
priv.call([File, Text], function(rstatus, rdata, rerror){
if (cb) cb(rstatus, rerror);
});
};
},
function (chromeWindow, args, cb) {
var [File, Text] = args;
if (!File) return cb(0, null, "need a filename");
try {
const unicodeConverter =
Cc["@mozilla.org/intl/scriptableunicodeconverter"]
.createInstance(Ci.nsIScriptableUnicodeConverter);
unicodeConverter.charset = "UTF-8";
Text = unicodeConverter.ConvertFromUnicode(Text);
const os = Cc["@mozilla.org/network/file-output-stream;1"]
.createInstance(Ci.nsIFileOutputStream);
os.init(File, 0x02 | 0x08 | 0x20, 0700, 0);
os.write(Text, Text.length);
os.close();
cb(1, null, null);
} catch (e) {
cb(0, null, "error writing file: "+e);
}
}
);
install_privileged_method(chromeWindow, domWindow, 'ReadFile',
function(priv) {
return function(File, cb) {
priv.call([File], function(rstatus, rdata, rerror){
if (cb) cb(rstatus, rdata, rerror);
});
};
},
function (chromeWindow, args, cb) {
var [File] = args;
if (!File) return cb(0, null, "need a filename");
try {
const is = Cc["@mozilla.org/network/file-input-stream;1"]
.createInstance(Ci.nsIFileInputStream);
const sis = Cc["@mozilla.org/scriptableinputstream;1"]
.createInstance(Ci.nsIScriptableInputStream);
is.init(File, 0x01, 0400, null);
sis.init(is);
var Text = sis.read(sis.available());
is.close();
cb(1, Text, null);
} catch (e) {
cb(0, null, "error reading file: "+e);
}
}
);
}
내가 테스트하지 않았다 이 코드. 위에서 쓴 것의 스트레이트 - 포워드 번역입니다 ... 그게 작동한다고 가정합니다!
두 가지 특별한 방법을 추가합니다. WriteFile
& ReadFile
을 선택한 window
개체로 웹 응용 프로그램의 (권한이없는) 자바 스크립트 코드에서 다음과 같이 사용할 :
var buffer = '...'; // the text to be written
window.WriteFile('C:\\path\\to\\file.txt', buffer, function(ok, errmsg) {
if (!ok) alert(errmsg);
});
window.ReadFile('C:\\path\\to\\file.txt', function(ok, buffer, errmsg) {
if (!ok) return alert(errmsg);
// use buffer here!
});
마지막으로, install_privileged_method
는 다음과 같이 정의된다 :
var install_privileged_method = (function(){
var gensym = (function(){
var __sym = 0;
return function() { return '__sym_'+(__sym++); }
})();
return function (chromeWindow, target, slot, handler, methodFactory) {
try {
target.__pmcache__ = target.hasOwnProperty('__pmcache__')
? target.__pmcache__
: { ticket_no: 0, callbacks: {}, namespace: gensym() };
target[slot] = methodFactory({ call: function(fargs, fcb) {
try {
var ticket_no = target.__pmcache__.ticket_no++;
target.__pmcache__.callbacks[ticket_no] = fcb;
var cevent = target.document.createEvent("CustomEvent");
cevent.initCustomEvent(
target.__pmcache__.namespace+'.'+slot,
true, true, { fargs: fargs, ticket_no: ticket_no }
);
target.dispatchEvent(cevent);
} catch (ue) {
fcb(0, null, 'untrusted dispatcher error: '+ue);
}
}});
LOG("installed untrusted dispatcher for method '"+slot+"'.");
target.addEventListener(
target.__pmcache__.namespace+'.'+slot,
function(cevent){
var ticket_no = cevent.detail.ticket_no;
var fargs = cevent.detail.fargs;
var fcb = target.__pmcache__.callbacks[ticket_no];
try {
handler(chromeWindow, fargs, fcb);
} catch (pe) {
fcb(0, null, 'privileged handler error: '+pe);
}
},
false,
true
);
LOG("installed privileged handler for method '"+slot+"'.");
} catch (ie) {
LOG("ERROR installing handler/factory for privileged "+
"method '"+slot+"': "+ie);
}
};
})();