firefox - Cross-window Javascript: is there a right way? - Stack Overflow

ProblemI'm trying to make a method that passes objects to a similar method in a popup window.I d

Problem

I'm trying to make a method that passes objects to a similar method in a popup window. I don't have control over the code in the target method, or the object passed in. The target method currently serialises the object, using JSON.stringify where possible, or instanceof Array.

The first problem with this is a bug in IE8 (see below). The second, and more fundamental, is that primitives are not the same across windows:

w = open("")
w.Array == Array               // returns false

Overriding on the popup any classes that might be passed in, and then restoring them after the call works, but it's really brittle and a maintenance headache.

Serialising the object into JSON and then parsing it in the context of the window hits the Firefox bug below.

I'm also a bit loathe to do a deep copy of the object or parse the JSON using new w.Object, etc. because it doesn't feel like it should be that plicated.

Can anyone suggest a sensible way to deal with this, or should I just accept that objects can't be passed verbatim between windows?


IE bug

JSON.stringify doesn't work across windows in IE8. If I pass an object to the popup, which attempts to serialise it, stringify returns undefined. To see this problem, open the script console in IE8 and try:

w = open("")
JSON.stringify(Object())          // returns "{}"
w.JSON.stringify(w.Object())      // returns "{}"

w.JSON.stringify(Object())        // returns "undefined" on IE8
JSON.stringify(w.Object())        // returns "undefined" on IE8
JSON.stringify([1, w.Object()])   // returns "[1,null]" on IE8

I tried working around this by setting w.JSON = JSON, but as the last test shows, that breaks when you have objects from both windows.

Firefox bug

It seems that calling w.Object() to create an object in Firefox in fact calls window.Object(). The same bug is hit when calling w.JSON.parse or w.eval. To see this, open Firebug's console and try:

w = open("")
new w.Object instanceof w.Object        // returns true

w.Object() instanceof w.Object          // returns false on Firefox 3.5
w.Object() instanceof Object            // returns true on Firefox 3.5
w.Object.call(w) instanceof Object      // returns true on Firefox 3.5
w.JSON.parse("{}") instanceof w.Object  // returns false on Firefox 3.5
w.JSON.parse("{}") instanceof Object    // returns true on Firefox 3.5
w.eval("[]") instanceof w.Array         // returns false on Firefox 3.5
w.eval("[]") instanceof Array           // returns true on Firefox 3.5
w.eval.call(w, "[]") instanceof Array   // returns true on Firefox 3.5

The only workaround I can see is parsing the JSON string myself.

Problem

I'm trying to make a method that passes objects to a similar method in a popup window. I don't have control over the code in the target method, or the object passed in. The target method currently serialises the object, using JSON.stringify where possible, or instanceof Array.

The first problem with this is a bug in IE8 (see below). The second, and more fundamental, is that primitives are not the same across windows:

w = open("http://google.")
w.Array == Array               // returns false

Overriding on the popup any classes that might be passed in, and then restoring them after the call works, but it's really brittle and a maintenance headache.

Serialising the object into JSON and then parsing it in the context of the window hits the Firefox bug below.

I'm also a bit loathe to do a deep copy of the object or parse the JSON using new w.Object, etc. because it doesn't feel like it should be that plicated.

Can anyone suggest a sensible way to deal with this, or should I just accept that objects can't be passed verbatim between windows?


IE bug

JSON.stringify doesn't work across windows in IE8. If I pass an object to the popup, which attempts to serialise it, stringify returns undefined. To see this problem, open the script console in IE8 and try:

w = open("http://google.")
JSON.stringify(Object())          // returns "{}"
w.JSON.stringify(w.Object())      // returns "{}"

w.JSON.stringify(Object())        // returns "undefined" on IE8
JSON.stringify(w.Object())        // returns "undefined" on IE8
JSON.stringify([1, w.Object()])   // returns "[1,null]" on IE8

I tried working around this by setting w.JSON = JSON, but as the last test shows, that breaks when you have objects from both windows.

Firefox bug

It seems that calling w.Object() to create an object in Firefox in fact calls window.Object(). The same bug is hit when calling w.JSON.parse or w.eval. To see this, open Firebug's console and try:

w = open("http://google.")
new w.Object instanceof w.Object        // returns true

w.Object() instanceof w.Object          // returns false on Firefox 3.5
w.Object() instanceof Object            // returns true on Firefox 3.5
w.Object.call(w) instanceof Object      // returns true on Firefox 3.5
w.JSON.parse("{}") instanceof w.Object  // returns false on Firefox 3.5
w.JSON.parse("{}") instanceof Object    // returns true on Firefox 3.5
w.eval("[]") instanceof w.Array         // returns false on Firefox 3.5
w.eval("[]") instanceof Array           // returns true on Firefox 3.5
w.eval.call(w, "[]") instanceof Array   // returns true on Firefox 3.5

The only workaround I can see is parsing the JSON string myself.

Share Improve this question edited Jan 21, 2010 at 12:13 munity wiki
16 revs
Mark 3
  • 1 The problem is not clearly defined, IMO. You need to tell us more what you are trying to do, and not as much on what the specific problem is. – Josh Stodola Commented Jan 20, 2010 at 23:11
  • 1 Maybe get rid of the problem altogether and use "popups" a'la lightbox (or one of its many clones) or something your favorite js lib provides - that way you'll get a consistent look across all browsers (the way popups are shown differs from a browser to a browser), no overriding headaches. Besides, popups are soooo 199x ;) (but who knows, maybe they are the best solution to your problem - I'm just generalizing here) – Igor Klimer Commented Jan 28, 2010 at 23:07
  • They're definitely not the best solution to my problem but sometimes you don't have that choice. – Mark Commented Jan 29, 2010 at 20:10
Add a ment  | 

4 Answers 4

Reset to default 1

For what it's worth, this is what I'm doing for now:

  • Ensure jquery-json is loaded in the popup window
  • Stringify the object
  • Call w.$.evalJSON(str), which binds primitives correctly
  • Pass that result to the method on the popup

Alternatively (if jquery-json is not available), you could inject the following script into the target:

<script type="text/javascript">
function parseJSON(j) {
  return JSON.parse(j)
}
</script>

as that will capture the popup's JSON, and not the caller's.

Any better solutions gladly appreciated.

If you are trying to do cross-domain scripting, seems like JSONP might be worth investigating.

I can't say I understand your problem fully, but there's an interesting window.name hack that's worth checking out: http://www.sitepen./blog/2008/07/22/windowname-transport/ (the blog post uses dojo but, of course, it can be done with pure JS too). It's safer than JSONP, easy to implement and it seems to work on all browsers.
Basically, it allows you to store any data, of any length in the window.name variable. What's awesome is that this variable doesn't get flushed/cleared on page change/refresh, so with some clever use of iframes you get simple and secure cross-domain transport :)

To see this, open Firebug's console and try:

Error: Permission denied for <stackoverflow> to get property Window.Object from <google>. On any line except first one: w = open("http://google.") Firefox 3.5.7

Think for a moment: You ar trying to open new window with arbitrary site and send to it data available to js. Seems too insecure to allow this.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745503322a4630514.html

相关推荐

  • firefox - Cross-window Javascript: is there a right way? - Stack Overflow

    ProblemI'm trying to make a method that passes objects to a similar method in a popup window.I d

    5小时前
    40

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信