问题
I have been working on a Safari extension and have hit a wall. I cannot figure out how to send multiple lines of data from global to the inject. I have been searching for a while on this site and others and only have found bits and pieces, but when combined fail.
Heres what I need to get out of Globalsafari.extension.secureSettings.username;
safari.extension.secureSettings.password;
I've tried puting them into global variables but the inject doesn't see those.
inject code
document.getElementById('local_login').style.display='';
document.getElementById('local_login_link').style.display = 'none';
document.loginForm.username.value = /*Safari Secure Settings Username*/
document.loginForm.password.value = /*Safari Secure Settings Password*/
document.getElementById('localsubmit').click();
I tried the code from the Apple documentation but it wouldn't run any of the inject code.
Edit Here is what I have so far. I'm just not sure why it isn't receiving, or sending.
Global.html
function sendCred() {
myUsername = safari.extension.secureSettings.username;
myPassword = safari.extension.secureSettings.password;
var arrayNSA = [myUsername, myPassword];
safari.self.tab.dispatchMessage("nsaArray", arrayNSA);
}
safari.application.addEventListener("messageFromNSA", sendCred, false);
Inject.js
function showForm() {
document.getElementById('local_login').style.display='';
document.getElementById('local_login_link').style.display = 'none';
document.loginForm.username.value = myNSAusername;
document.loginForm.password.value = myNSApassword;
document.getElementById('localsubmit').click();
}
function recieveCred(msgEvent) {
var nsaMessageName = msgEvent.name;
var nsaMessageData = msgEvent.message;
if (nsaMessageName === "nsaArray") {
var myNSAusername = nsaMessageData[0];
var myNSApassword = nsaMessageData[1];
showForm();
}
}
function disbatchData() {
var nflksnfll = "Give me my data";
}
safari.self.addEventListener("nsaArray", recieveCred, false);
safari.self.tab.dispatchMessage("msgFromNSA", disbatchData);
回答1:
There are a few problems with your scripts.
In your global script:
- You need to register the event listener on the "message" event; "messageFromNSA" is not a valid event type. Also, you need to use
safari.application.addEventListener
rather thansafari.self.addEventListener
. - In function
sendCred()
, changesafari.self.tab.dispatchMessage
toevent.target.page.dispatchMessage
, because you want to dispatch the message to the page that sent the request.event.target
is the tab that sent the message;page
is the proxy for the document in that tab.safari.self.tab
only works inside injected scripts.
In your injected script:
- Again, the event listener needs to be registered on "message", not "nsaArray".
- In function
recieveCred(msgEvent)
, you have definedmyNSAusername
andmyNSApassword
as local variables, so functionshowForm()
cannot see them. Remove the keywordvar
to make them global variables.
Here are revised global and injected scripts that should work, with additional comments.
Global script:
function handleMessage(event) {
// use a switch statement and a more generic function name
// so you can use it to handle other messages in the future
switch (event.name) {
case 'sendNsaArray': {
// I changed the name of the message sent from the
// injected script to 'sendNsaArray'
var myUsername = safari.extension.secureSettings.username;
var myPassword = safari.extension.secureSettings.password;
var arrayNSA = [myUsername, myPassword];
event.target.page.dispatchMessage('nsaArray', arrayNSA);
break;
}
}
}
safari.application.addEventListener("message", handleMessage, false);
Injected script:
function showForm(username, password) {
// why not pass the values to this function instead of using globals
document.getElementById('local_login').style.display = '';
document.getElementById('local_login_link').style.display = 'none';
document.loginForm.username.value = username;
document.loginForm.password.value = password;
document.getElementById('localsubmit').click();
}
function handleMessage(event) {
// again using a more generic function name
switch (event.name) {
case 'nsaArray': {
showForm(event.message[0], event.message[1]);
// passing the username and password to showForm()
// instead of storing them in global variables
break;
}
}
}
if (window === window.top) {
// this conditional prevents the injected script from
// working inside iframes
safari.self.addEventListener('message', handleMessage, false);
safari.self.tab.dispatchMessage('sendNsaArray');
// not necessary to send any data with this message
}
回答2:
You can access the global page with
const myGlobal = safari.extension.globalPage.contentWindow;
alert (myGlobal.my_variable);
来源:https://stackoverflow.com/questions/8739047/safari-extension-messaging