By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,641 Members | 2,085 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,641 IT Pros & Developers. It's quick & easy.

keeping a persistent reference to an object

P: n/a
Hi!

Does anybody know of a way that I can keep a reference to an object
that I can then reuse? I tried various approaches using navigator, but
these all fail in an iframe due to premission problems.

For e.g.:

navigator.stuff = 5;

will work fine so long as this is done in the top level window. But if
I then do:

alert(navigator.stuff);

in a child iframe, i get 'undefined'... almost as thought I were
refering to a different navigator object (??). What gives?

Furthermore, if I then try refering instead to top.navigator or
parent.navigator, I get permission denied errors, presumably due to the
fact that my iframe is coming from a different URL than its parent.

There must be some sneaky underhanded way of doing this (using a hidden
frame maybe?), but I'm at my wit's end here!

Help!

Thanks,
Marc

Sep 17 '05 #1
Share this Question
Share on Google+
12 Replies


P: n/a


ma********@gmail.com wrote:

Does anybody know of a way that I can keep a reference to an object
that I can then reuse? I tried various approaches using navigator, but
these all fail in an iframe due to premission problems.
Furthermore, if I then try refering instead to top.navigator or
parent.navigator, I get permission denied errors, presumably due to the
fact that my iframe is coming from a different URL than its parent.

There must be some sneaky underhanded way of doing this (using a hidden
frame maybe?), but I'm at my wit's end here!


With frames/windows from different origins you will always run into the
same origin policy disallowing you access.

If you have a frameset document and frame documents from the same origin
then frames should be able to store stuff in
parent.variableName
as long as the frameset document does not get reloaded.

Same for a HTML document with iframes from the same origin, the iframes
can store stuff in
parent.variableName
as long as the parent document is not reloaded.

--

Martin Honnen
http://JavaScript.FAQTs.com/
Sep 17 '05 #2

P: n/a
ASM
ma********@gmail.com wrote:
Hi!

Does anybody know of a way that I can keep a reference to an object
that I can then reuse? I tried various approaches using navigator, but
these all fail in an iframe due to premission problems.

For e.g.: navigator.stuff = 5;


Main page :

self.stuff = 5;
or :
stuff = 5;
or/and :
if(!!parent.myIframe.stuff)
parent.myIframe.stuff = 5;
Called page :

if(!!parent.stuff)
stuff = parent.stuff;
else
alert('error with \'stuff\' !');
And if that doesn't work, try something as :

Main page :

<html>
<head>
<script type="text/javascript">
function send(page,attrib,target)
target.location.href=page+'?'+attrib;
}
</script>
</head>
<body>
<a href="pge1.htm" target="myIframe"
onclick="send(this.href,this.target,'stuff=5&name= \'foo\'');
return false;">page 1</a>

<a href="pge2.htm"
onclick="send(this.href,'self','stuff=25&name=\'tr ick\'');
return false;">page 2</a>
</body></html>

Called Page :

<html>
<head>
<script type="text/javascript">

function receiv(){
var attrib = this.location.search;
attrib = attrib.substring(1).split('&');
for(var i=0;i<attrib.length;i++)
eval(attrib[i]);
}
receiv()

if(!!name)
alert('name = '+name);
else
alert('no variable \'name\' or ...\nfunction broken');

</script>
</head>
</html>

--
Stephane Moriaux et son [moins] vieux Mac
Sep 17 '05 #3

P: n/a
ma********@gmail.com wrote:
Does anybody know of a way that I can keep a reference
to an object that I can then reuse? I tried various
approaches using navigator, but these all fail in an
iframe due to premission problems.

For e.g.:

navigator.stuff = 5;

will work fine so long as this is done in the top level
window. But if I then do:

alert(navigator.stuff);

in a child iframe, i get 'undefined'... almost as
thought I were refering to a different navigator
object (??). What gives?
You are referring to a different - navigator - object. Each
global/window object has its own - navigator - object and each
window/frame/iframe has its own global/window object (interrelated
through the - top - and - parent - references and the - frames -
collection).
Furthermore, if I then try refering instead to
top.navigator or parent.navigator, I get permission denied
errors, presumably due to the fact that my iframe is coming
from a different URL than its parent.
Cross-domain security restrictions. You can get around them if you are
working in different sub-domains but if the desire is to script across
actual domains then you are wasting your time (unless the result is for
an Intranet and you can dictate browser security settings).
There must be some sneaky underhanded way of doing
this
Doing what exactly? Explain the actual requirement (i.e. answer the
question: why?), and in detail.
(using a hidden frame maybe?),

<snip>

If cross-domain security is the problem another frame is unlikely to be
the solution as it can only belong to one domain itself.

Richard.
Sep 17 '05 #4

P: n/a
ma********@gmail.com wrote:
Hi!

Does anybody know of a way that I can keep a reference to an object
that I can then reuse? I tried various approaches using navigator, but
these all fail in an iframe due to premission problems.

For e.g.:

navigator.stuff = 5;

will work fine so long as this is done in the top level window. But if
I then do:

alert(navigator.stuff);

in a child iframe, i get 'undefined'... almost as thought I were
refering to a different navigator object (??). What gives?

Furthermore, if I then try refering instead to top.navigator or
parent.navigator, I get permission denied errors, presumably due to the
fact that my iframe is coming from a different URL than its parent.

There must be some sneaky underhanded way of doing this (using a hidden
frame maybe?), but I'm at my wit's end here!


Howdy

First off , cross-domain javascript references are going to fail,
unless your someone like me who simply proxies pages into my own domain
namespace via server side toys that read the source from any site
via sockets and then pump it out from my own.

As to your navigator object , try self.stuff=5; and then have your pages
reference that value with the full javascript path. (frame included)
--
--.
--=<> Dr. Clue (A.K.A. Ian A. Storms) <>=-- C++,HTML, CSS,Javascript
--=<> http://resume.drclue.net <>=-- AJAX, SOAP, XML, HTTP
--=<> http://www.drclue.net <>=-- SERVLETS,TCP/IP, SQL
--.
Sep 17 '05 #5

P: n/a
First off, many many thanks for all the patient explanations!

Now, just to clarify the issue:
I'm not interested in passing information between the parent and the
child per sei. This was just a method that I had played around with in
order to achieve my goal. The objective here is simply to keep a
reference to an object that stays when the page is reloaded.
I figured the obvious place to assign such a reference would be in the
navigator object. Something like:

alert('before assignment: ' + navigator.stuff);
navigator.stuff = 5;
alert('after assignment: ' + navigator.stuff);

which works fine in the parent (root) window, but fails inexplicably in
the child iframe. That is to say, in the parent, one sees "before
assignment: undefined" and then "after assignment: 5" the first time.
Then on every subsequent visit, one sees "before assignment: 5", since
the value of stuff has been assigned. However, if you try this in the
child iframe, you will always get "before assignment: undefined".

To be sure, I'm not bent on storing reference to stuff in navigator.
Any old place would be fine, just so long as it sticks around.

Thanks again to all!

Sep 18 '05 #6

P: n/a
ma********@gmail.com wrote:
<snip>
The objective here is simply to keep a
reference to an object that stays when the page is reloaded.
I figured the obvious place to assign such a reference would be in the
navigator object. Something like:

alert('before assignment: ' + navigator.stuff);
navigator.stuff = 5;
alert('after assignment: ' + navigator.stuff);


That aint really gonna get it.

You have to keep in mind where the code is actually running
that sets the value , in relation to where the code is actually running
that reads the variable.

lets say I had a frameset something like

<frames>
<frame rows ="50%,50%,*">
<frame src="pageA.html" name="pageA">
<frame src="pageB.html" name="pageB">
<frame src="blank.html" name="secretframe">
</frameset>
</frames>

Now as you can see
we have pageA.html that takes up 50% of the screen
we have pageB.html that takes up 50% of the screen
and we have blank.html that takes up the remainder (*) which in this
case is nothing (at least nothing visible)
So from any of these frames I could store values in either the
"top" which is the document holding the three frames, as in
top.stuff=5. If the top frame holding your framest was itself in frames
then that containing frame would become "top", but for pageA,pageB and
secret, there is another name called "parent" which always referes to
the the immeadiately containing frame. I prefere using parent
as opposed to top, as it works no matter how much nesting occurs

Now if pageA ,pageB, or Secret are reloaded the values in top.stuff
or parent.stuff (same thing in your case) will remain, which you can
test with script in any of those pages by setting and getting top.stuff
from any of those frames

you can also reach from pageA to PageB or secret with
parent.pageA.stuff=parent.pageB.stuff or parent.pageA.stuff ="foo"

Now if the user reloads the entire framset , your sand castle will
be blown away (variables page and all)

To servive this , there is a place in every document called
document.cookie

The cookie does exactly what you want , in that it will hold a value
in the users browser for hours , days ,months etc , and as soon
as that browser comes back to your page, the document.cookie
will still have that value.
Searching arround will find you some cookie code , or you can snag it
with my DHTML kit in the DHTML section of my site. cokkies
are not exactly as simple as document.cookie="foo" and require a little
formatting , but even if the user closes their browser , shuts down
their computer, that value will still be their when the boot up and
visit your site.

--
--.
--=<> Dr. Clue (A.K.A. Ian A. Storms) <>=-- C++,HTML, CSS,Javascript
--=<> http://resume.drclue.net <>=-- AJAX, SOAP, XML, HTTP
--=<> http://www.drclue.net <>=-- SERVLETS,TCP/IP, SQL
--.
Sep 19 '05 #7

P: n/a
Cookies are great for holding strings, but what I need to store is a
reference to an object. This object happens to be a sort of
connection, which must be opened on creation, so unless there's some
way to serialize & deserialize this connection object (which I don't
know), I don't think a cookie is going to cut it for me. Besides, I'm
only interested in keeping this connection around for the life of the
browser.

Thanks anyway for the thoughts.

Sep 19 '05 #8

P: n/a
ma********@gmail.com wrote:
Cookies are great for holding strings, but what I need to store is a
reference to an object. This object happens to be a sort of
connection, which must be opened on creation, so unless there's some
way to serialize & deserialize this connection object (which I don't
know), I don't think a cookie is going to cut it for me. Besides, I'm
only interested in keeping this connection around for the life of the
browser.


I store objects in cookies all the time. One simply
needs to marshal the object to and from a string.

for(i in yourObject){.....}

iterates through yourObject, and from their you should
be able to figure it out.

If not , check out my DHTML library and look for the functions
DCo2a() and DCa2o()
--
--.
--=<> Dr. Clue (A.K.A. Ian A. Storms) <>=-- C++,HTML, CSS,Javascript
--=<> http://resume.drclue.net <>=-- AJAX, SOAP, XML, HTTP
--=<> http://www.drclue.net <>=-- SERVLETS,TCP/IP, SQL
--.
Sep 19 '05 #9

P: n/a
I took a look at your DCo2a and DCa2o methods, but they don't seem to
traverse the object tree (unless I'm mistaken). That is, for an
references to other objects it just outputs "[object]". Just for the
record, here's my stab at marshalling/unmarshalling objects:

function marshall(object, shouldMarshallFunctions) {
var objectAsStr = new String();
var isFirstVal = true;
// the _ is to work around the fact that JavaScript regexp seems to
lack negative look-behind assertions
for (var key in object) {
var val = object[key];
var type = typeof(val);
if (type == 'undefined' || (type == 'function' &&
!shouldMarshallFunctions)) continue;
if (!isFirstVal) objectAsStr += '_|';
isFirstVal = false;
if (type == 'object') {
objectAsStr += key + '_=_{' + marshall(val) + '_}';
} else {
val = val.toString();
val = val.replace(/\\/g, '\\\\');
val = val.replace(/([=\|\{\}])/g, '\\$1');
if (type == 'function') objectAsStr += 'function ';
objectAsStr += key + '_=' + val;
}
}
return objectAsStr;
}

function unmarshall(objectAsStr) {
var object = new Object();
var assignments = objectAsStr.split(/_\|/);
// var assignments = objectAsStr.split(/(?<!\\)\|/); // fails! no
negative look behind assertions in JavaScript regexp
for (var i in assignments) {
document.body.innerHTML = '<code>' + assignments[i] + '</code>';
var indexOfEq = assignments[i].indexOf('_=');
var key = assignments[i].substring(0, indexOfEq );
var val = assignments[i].substring(indexOfEq + 2);

key = key.replace(/\\([=\|\{\}\\])/g, '$1');
val = val.replace(/\\([=\|\{\}\\])/g, '$1');
// alert(key + ' = ' + val);
if (val.indexOf('function ') == 0) {
// treat functions
var funcName = key.substring('function '.length);
object[funcName] = eval(val);
} else if (val.indexOf('_{') == 0 && val.indexOf('_}') == val.length
- 2) {
// treat object references
val = val.substring(2, val.length - 2);
val = unmarshall(val);
object[key] = val;
} else {
// treat primitive types
object[key] = val;
}
}
return object;
}
These functions recursively traverse the object tree, as well as
optionally handling the copying of functions.
Anyway... after all that, I still don't think this is going to work.
Turns out my connection object is unexpectedly vast, and it takes far
too much cpu time to serialize it. I'll keep hacking at it anyway.

Cheers,
Marc

Sep 21 '05 #10

P: n/a
ma********@gmail.com wrote:
I took a look at your DCo2a and DCa2o methods, but they don't seem to
traverse the object tree (unless I'm mistaken).
That is, for an
references to other objects it just outputs "[object]". Just for the
record, here's my stab at marshalling/unmarshalling objects:

No, your not mistake. The functions there just seemed to
be the simplest ones I could find that could convey the nut of it.

function marshall(object, shouldMarshallFunctions) {
var objectAsStr = new String();
var isFirstVal = true;
// the _ is to work around the fact that JavaScript regexp seems to
lack negative look-behind assertions
for (var key in object) {
var val = object[key];
var type = typeof(val);
if (type == 'undefined' || (type == 'function' &&
!shouldMarshallFunctions)) continue;
if (!isFirstVal) objectAsStr += '_|';
isFirstVal = false;
if (type == 'object') {
objectAsStr += key + '_=_{' + marshall(val) + '_}';
} else {
val = val.toString();
val = val.replace(/\\/g, '\\\\');
val = val.replace(/([=\|\{\}])/g, '\\$1');
if (type == 'function') objectAsStr += 'function ';
objectAsStr += key + '_=' + val;
}
}
return objectAsStr;
}

function unmarshall(objectAsStr) {
var object = new Object();
var assignments = objectAsStr.split(/_\|/);
// var assignments = objectAsStr.split(/(?<!\\)\|/); // fails! no
negative look behind assertions in JavaScript regexp
for (var i in assignments) {
document.body.innerHTML = '<code>' + assignments[i] + '</code>';
var indexOfEq = assignments[i].indexOf('_=');
var key = assignments[i].substring(0, indexOfEq );
var val = assignments[i].substring(indexOfEq + 2);

key = key.replace(/\\([=\|\{\}\\])/g, '$1');
val = val.replace(/\\([=\|\{\}\\])/g, '$1');
// alert(key + ' = ' + val);
if (val.indexOf('function ') == 0) {
// treat functions
var funcName = key.substring('function '.length);
object[funcName] = eval(val);
} else if (val.indexOf('_{') == 0 && val.indexOf('_}') == val.length
- 2) {
// treat object references
val = val.substring(2, val.length - 2);
val = unmarshall(val);
object[key] = val;
} else {
// treat primitive types
object[key] = val;
}
}
return object;
}
These functions recursively traverse the object tree, as well as
optionally handling the copying of functions.
Anyway... after all that, I still don't think this is going to work.
Turns out my connection object is unexpectedly vast, and it takes far
too much cpu time to serialize it. I'll keep hacking at it anyway.


So am I to understand that *all* the entries in this giant object
are data needing state maintenace , or is it just a subset that needs
the state-maintenance.

What is the nature of the data?

--
--.
--=<> Dr. Clue (A.K.A. Ian A. Storms) <>=-- C++,HTML, CSS,Javascript
--=<> http://resume.drclue.net <>=-- AJAX, SOAP, XML, HTTP
--=<> http://www.drclue.net <>=-- SERVLETS,TCP/IP, SQL
--.
Sep 21 '05 #11

P: n/a
If you really want to know, it's a JSJaCHttpBindingConnection, which
you can find here:
http://www.jabberstudio.org/cgi-bin/...js?view=markup
It "extends" JSJaCConnection, which you will find here:
http://www.jabberstudio.org/cgi-bin/...js?view=markup

Right now, I'm trying to figure out which attributes I really need to
save so I can stick them in cookies and try to re-establish the
original state of the connection without actually reconnecting.

btw, Those marshall and unmarshall function I posted don't work, since
all data is treated as strings. They need a set of if statements like
"if (type == 'integer') ..." and so on. But... I'm not doing this
anymore.

Fun.

Sep 22 '05 #12

P: n/a
ma********@gmail.com wrote:
If you really want to know, it's a JSJaCHttpBindingConnection, which
you can find here:
http://www.jabberstudio.org/cgi-bin/...js?view=markup
It "extends" JSJaCConnection, which you will find here:
http://www.jabberstudio.org/cgi-bin/...js?view=markup
Sorta looks like a giant RPCish animal over XMLHTTP
Right now, I'm trying to figure out which attributes I really need to
save so I can stick them in cookies and try to re-establish the
original state of the connection without actually reconnecting.
Yiff , that resembles work, I'm getting a rash already ;)
btw, Those marshall and unmarshall function I posted don't work, since
all data is treated as strings. They need a set of if statements like
"if (type == 'integer') ..." and so on. But... I'm not doing this
anymore.


Have fun and remember for(i in object){} is your friend.
A few minutes getting it to do a deep object traversal
will make it fairly easy to get a map of the state
that you can dump to innerHTML somewhere.
--
--.
--=<> Dr. Clue (A.K.A. Ian A. Storms) <>=-- C++,HTML, CSS,Javascript
--=<> http://resume.drclue.net <>=-- AJAX, SOAP, XML, HTTP
--=<> http://www.drclue.net <>=-- SERVLETS,TCP/IP, SQL
--.
Sep 23 '05 #13

This discussion thread is closed

Replies have been disabled for this discussion.