4

I have two web pages. On the first page I have to submit a form. Using the values from the form (using embedded JavaScript code), I need to generate another JavaScript file and use this generated JavaScript file in the next page. How can this be done? Or is there a better way of doing this?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ankur Ankan
  • 2,953
  • 2
  • 23
  • 38
  • Have you tried Submit to a code in PHP (for example), and then returning the content of this new JS? – wendelbsilva Aug 01 '13 at 21:00
  • @wendelbsilva: I want to make the whole thing work on the client side. So can't use PHP. – Ankur Ankan Aug 01 '13 at 21:02
  • If you want to transfer _JavaScript_ data across pages without doing things server-side, look into _localStorage_ and _sessionStorage_ https://developer.mozilla.org/en-US/docs/Web/Guide/DOM/Storage – Paul S. Aug 01 '13 at 21:03
  • 2
    What are you _really_ trying to do here? What is the end goal? You can pass GET variables easily to another page if you need that. – Benjamin Gruenbaum Aug 01 '13 at 21:04
  • @AnkurAnkan You can try creating a new element of type "script", set attribute type to "text/javascript", and them put inside this new element the JS you generated. Something like [this](http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml). – wendelbsilva Aug 01 '13 at 21:05
  • @BenjaminGruenbaum: On the first page I am taking some code as input and using the embedded js I am trying to generate some stack trace. And using the second page for visualizing the stack trace. Since the second page is already written and I don't want to modify it so need to pass the value generated from the first page to the second. And the traces are very long strings. – Ankur Ankan Aug 01 '13 at 21:09
  • 2
    In that case localStorage is probably your best bet, passing GET params is probably not enough. Probably shoot for a single page application though that'd completely eliminate your problem. – Benjamin Gruenbaum Aug 01 '13 at 21:12
  • How deep is this? How sensitive is the data? How much data is there? This can be handled through the query string (GET params), or Cookies, but if you can't use HTML5's localStorage, or if it's too much, you can look at server storage and retrieval via AJAX or websockets. – vol7ron Aug 01 '13 at 21:35
  • @vol7ron: The sensitivity of the data doesn't matter. And the data is huge (might even be in MB's). – Ankur Ankan Aug 01 '13 at 21:47

3 Answers3

11

Same origin?

Documents of the same origin is always allowed to interact with each other. If code in one window or frame can refer to another window or frame, and they are of the same origin, then JavaScript in one execution context (window or frame..!) can interact with the other. You get such a reference to a foreign Window object as a return value when you invoke window.open()! Thus use that reference to set whatever variables you want on that Window or load new scripts as you please.

Cross document messaging

If the documents are not of the same origin, or you have not a reference to the other execution context, then you must use a new API introduced in HTML5. It is called the "postMessage API" and are surprisingly well supported. Even IE 8 supports it!

Here is a simple way you can check for browser support of this feature:

if (typeof window.postMessage !== undefined)
    console.log("postMessage API is supported!");

Here is an example of how to send a hello world text to a dummy recipient:

window.postMessage("Hello world", "www.dummy.com");

And here is how you would listen for such messages in another JavaScript hosted somewhere else:

window.addEventListener("message", function(event) {
    if (event.origin === "www.dummy.com")
        console.log("Received message: " + event.data);
    }, true);

IE11 may have some issues with this and is not supported in previous versions at all.

Dynamically load a JavaScript

Whenever you have succeeded in establishing a communication channel between the two, and passing simple data won't suffice, then you can always pass a full blown JavaScript to the other party and have him execute that script. Please see this stackoverflow question and his related answers to learn more how you would implement such a solution on the receiving end.

Of course these has just been a few short examples, you should google the rest. Hope it helped you pick up a path at least.

Community
  • 1
  • 1
Martin Andersson
  • 18,072
  • 9
  • 87
  • 115
1

You can do what you're looking for by using Blobs. In order to actually run JavaScript on another page though, you'll need the HTML for that page too.

A not so clean example that works...

var script = function callme(){alert('hi!');};
var html = '<!DOCTYPE html><html><head><script type="text/javascript">'+script.toString()+'</script><body><a onclick="callme();return false;" href="javascript:void(0);">Click me!</a></body></html>';
window.open(URL.createObjectURL(new Blob([html],{type:'text\/html'})));

It only works in the more recent browsers though, such as Chrome 20+, Firefox 13+, IE 10+, and in Safari 6+. More info about Blobs here: https://developer.mozilla.org/en-US/docs/Web/API/Blob

Pluto
  • 2,900
  • 27
  • 38
0

One possible option for a situation like this (and I'm well aware it won't suit everyone) is to go the less-fancy route, and put the visible page(s) into an iframe that fills the viewport; then just have the parent window hold on to the data. The iframe will navigate from your page 1 to page 2, but since the parent window doesn't change, it's a stable repository for as many MB of javascript data as you like. This is also going to be simpler and more efficient than just about any other cross-window communications technique you could use, given the quantity of data involved, and it'll work in every browser all the way back to Netscape Navigator (probably! ;-) ).

Or for related solution, display page 2 in an iframe that you insert into page 1 that again, fills the screen and covers the existing content. Since page 1 still exists and can share data with the iframe, once again you have no problem.

Doin
  • 7,545
  • 4
  • 35
  • 37