Executing javascript from within an iframe - javascript

I have:
A web server (server 1)
An application server running some beast of a legacy web app (server 2)
An iframe on server 1 pulling in the application from server 2
My problem is:
The legacy app uses JS validation on its forms. When a user attempts to submit an incomplete form, an alert pops up to notify the user that they are a dummy. Of course, this fails when the app is run inside of an iframe because server 1 and server 2 live at different domains.
I tried setting the following proxy directives on server 1:
ProxyPass /legacy_app http://server2.url/legacy_app
ProxyPassReverse /legacy_app http://server2.url/legacy_app
I'm now able to serve the iframe from http://server1.url/legacy_app, but I'm still unable to execute javascript inside that iframe -- I get the same security/access errors as I did when the app was running on a different domain.
Is there something else I can try?

How is the legacy app checking if the boxes are filled in? Simple javascript? Ajax?
The alert box itself should still work. I'm thinking the code for determining if the alert should be issued might be what's broken.
Running the following code on my local apache server still gives me the alert onLoad even though the page is on a remote host:
<html>
<body>
<div>
<iframe src="http://www.crowderassoc.com/javascript/alertbox.html" width="300" height="200">
</div>
</body>
</html>
Try copying the above code to a page on server #1 and see if you get the alert box from that remote site in the iframe.

Have you tried hosting the script inside of a .js file hosted on server #1 but running out of the iframe (referenced out of server #2)?
I think a browser is okay with referencing an external site, but doesn't like it when it is referenced by an external site.
Haven't tried it myself, but I believe that's how I've heard of this sort of a problem being worked around. I know this is the method that Google Analytics uses - you have to request the .js file from Google's servers, but once it's there, it has access to the browser.

Joe, I think you are correct. A quick test with other servers shows that I can trigger alerts from remotely-hosted scripts quite easily.
The legacy server is the client's and we don't have easy access to it, but glancing at their JS it looks like they're doing some sort of cross-site/framing detection -- worth further investigation.

I've had this situation in the past where I was trying to build an app around a heavily scripted pre-existing app on a remote server, and the app would run fine if it was opened in its own window, but if I tried loading it into a frame, it would break.
What I ended up doing for this project was opening the local application in a pop-up with a width of 495px, loading the external app in the main (already existing) window, resizing the main external app window to the screen width minus 495px, and positioning the windows side by side on the screen. This gave the end user a similar effect to what I had been trying to do with frames, only it worked.
In case it helps, here is the code I used from my index.php file:
// Manipulating the current window
window.location.href = 'http://www.someExternalApp.com'; // setting the page location.
window.name = 'legacyapp'; // setting the window name just the for heck of it.
moveTo(0,0); // moving it to the top left.
// Resizing the current window to what I want.
mainWindowWidth = screen.width - 495;
mainWindowHeight = screen.height; // Makes the window equal to the height of the users screen.
resizeTo(mainWindowWidth,mainWindowHeight);
// function for opening pop-up
function openWin(){
win2 = window.open(page,'',winoptions);
win2.focus();
}
// internal app location (for use in pop-up)
page = 'someLocalApp.php';
// internal app Window Options (for pop-up)
winoptions = 'width=490,height='+mainWindowHeight+',top=0,left='+mainWindowWidth+'leftscrollbars=1,scrolling=1,scrollbars=1,resizable=1,toolbar=0,location=0,menubar=0,status=0,directories=0';
// Opens the local app pop-up
openWin();

Related

Cannot get reference to one page from another

I am working on a web app that needs to have two parts. The one is a controller and the other is a display. Something like Google Slides in presentation mode. The controller has a button to launch the display:
<script language="JavaScript">
function OpenMain()
{
var MainPage = window.open("TheUltraSignalLite.html");
TimerIMG = MainPage.document.getElementById("TimerIMG");
TimerIMG.src = "TM-Full-Blue.jpg";
}
</Script>
The call to window.open seems to return null. I have tried Chrome, Edge, Firefox, and Opera and they all have the result. These are all local files for now, but I might put in on a web server someday. I have seen some answers that want you to turn off security, but I cannot ask everyone who uses this app to turn off security. How do I get a valid reference to the display window?
Edit 1:
Yes, window.open from the local disk does cause a CORS restriction.
I tried this where both files are in the same AWS S3 Bucket, so the CORS should not be an issue. But I still get a null on the window.open. If I put a breakpoint on the first line, then everything worked. If I split the open and the rest of the code into two functions with two buttons, it works. So it looks like I have to find a way to run the open in an async way.
Edit 2
My solution to keep it simple was to put the window.open in the OnLoad event. This opens the child window and allows it to fully render and the value of MainPage is ready to use. (I changed the MainPage to a global variable.) I still have to run it from some type of web server, rather than loacl file, but that is not a big deal.
If you are not allowed to access the new window content, then the problem you are encountering is a basic security feature of web browsers. Citing mdn:
The returned reference can be used to access properties and methods of the new window as long as it complies with Same-origin policy security requirements
To read more about Same-origin policy
If your new window respects the Same-origin policy, then you can access the content of the new window with for example:
// Open index.html from the current origin
const newWindow = window.open('index.html')
const h1 = newWindow.document.querySelector('h1')
If you want to avoid asking users for pop-up permission, then you should probably use a link instead of a pop-up.

FileMaker Web Viewer javascript step fails when used as a local file: window.open()

I ran into an odd issue with a bit of Javascript that is running in a Web Viewer (WV) in a FileMaker database. (For those that don't know, FileMaker is an integrated UI/DB platform which has a 'web viewer' object, which is a cut down version of a web browser that runs inside the solution. It is NOT a full web browser.)
We have had this WV+Javascript working for quite a while now, in files that are hosted using FileMaker Server (FMS). There's a button on a layout that opens a pop-out window that contains this web viewer. This web viewer is a media player, with pause/play buttons; it has some special functions for capturing the current video position and reporting it back to the database: it has some buttons and reads keystrokes, and calls back to the open FMP file to affect changes there. Again, this has been working fine when the file is hosted on FMS.
But then we wanted to make a trial/demo version of this file, and have the user run it locally or offline. In testing this offline file it was noticed that the pop-out window web viewer stopped calling back to the open file. (FileMaker Pro also registers a new URL scheme, "fmp://". This can be used to make callbacks to the database from web viewers that are inside that database. So the code was changed to use the '$' reference in the "fmp://" URL, which causes the FileMaker client software to reference the currently open file of the given name.) But even with that fixed, there was one step that was failing still.
To effect these 'callback' events from the WV+javascript to the FM file, the javascript was using this code:
window.open('fmp://' + fmdbHost + '/' + fmdbFilename + '?script=keyPressed&param=' + e.keyCode, 'form_b');
(Here, the variable 'fmdbhost' = "$", as noted; 'fmdbFilename' =(nameoftheopenfile); 'e.keyCode'=(keypressed); "form_b" is an iframe that is defined in the HTML of the page.) This code (when it's working on the hosted environment) does not actually open a new window; that's OK, I don't want it to open a new window. It just a technique used to execute the URL and trigger functionality in the FileMaker world.
My solution/workaround, was to instead use this code:
window.location.href = ( 'fmp://' + fmdbHost + '/' + fmdbFilename + '?script=keyPressed&param=' + e.keyCode );
This appears to work out just fine, but I'm curious to know why the original step was failing when it's run locally. This was working if the file was hosted...so why would that fail if the file is being run locally? Does it do some kind of URL verification, and not like the "fmp://" or perhaps the "$" part? If so...why isn't it doing this when using 'window.location'? (If I used the original 'fmdbHost' definition - which used an IP Address - it would at least execute the window.open() method and attempt to open the "fmp://" URL. It's just that when run locally this ended up being the wrong file - it needs to use the "$" reference to affect the currently open file.)
The specification for 'window.open()' indicates that the second parameter is a window name (sounds more like a reference to the new window). So in the original code the 'form_b' reference is attempting to reuse the iframe defined in the HTML as the conduit for the call. But is that iframe even an actual window 'reference' initially? Does something parse the DOM and extract iframes and add them to the list of current 'windows'?
I'm using FM 15.01 for testing/development, on OS X 10.11.6. Ultimately, this will have to run on Windows as well...but that can be ignored for now.
Thanks,
J

How to get data from an external site inside a cordova application?

Scenario:
I've an application made in angularJS and ionic for cordova 3.5
This application loads trough an iframe a web to make some things with a step by step form. This web is on other site.
The code for the html is:
<div id="IframeContainer">
<iframe src="URL" style="width:100%;height:90%" onLoad="checkforclose(this);"></iframe>
</div>
This step-by-step form returns a result that the cordova application needs to know what happens in the form. It can return a json, a text/plain or even an HTML that auto-post to another site (This is linked with this non-answered question: Post and redirect FROM Web Api)
Said this, in my cordova application I've a javascript function in order to close the iframe and take over again the control of my application, detecting if the url contains the word "close". This is the code:
<script type="text/javascript">
function checkforclose(pageURL) {
var urlFrame = pageURL.contentWindow.location;
if (urlFrame.href.indexOf('close') > -1) {
window.location = "#/employees/";
}
}
</script>
Question:
Trying avoid CORS (So I think I can't read the iframe content on load, or I'm wrong?),
without using jQuery (AngularJS is welcome, plain javascript even more)
Taking over the control again to the application
How can I get the data returned by the step-by-step external form?
UPDATE 1:
I tried coding a "onload" reading (CORS errors), and posting to a cordova-html page, but without any respectable result.
A possible solution is Web messaging or cross-document messaging. Here's a blog post where someone used this method to gain access to a mobile device's camera from an external page loaded in an iframe. Although this person had the opposite goal (get data from Cordova to page loaded in iframe), they were able to accomplish cross domain communication between a page in an iframe and Cordova; which is what I believe you are trying to do.

node-webkit running a function from external source

I am loading a remote page with an iframe in node-webkit app.
I would like to run a function from the node.js app from the webpage.
In app.js i have
var xxx = function(){ console.log('test'); }
and in http://www.test.com/index.html i have tried:
window.xxx();
xxx();
global.xxx();
But nothing seems to work.
How can i do that?
Many thanks
If I understand correctly, you want to access a function that's defined in the remote page that you are including as an iframe in your current page, right?
There are two separate issue here, I think.
First, you need to have a handle on the iframe, then access that window's environment through the 'contentWindow' property of the iframe dom element, i.e. given an iframe with id foo, that points to a page with a function named bar, you could do this:
x = document.getElementById('foo');
x.bar();
This works fine for me with a local page, but the other issue is that you might find some difficulty with running a remote page in an iframe and still having access. If it's a page under your control, that might work, but some pages don't like to be run in iframes, so then you have to sandbox to some extent, which may interfere with your ability to access it in this way. It's been a while since I played with sandboxing, so I'm not sure, but if it's a page you control, you should be able to set it up so it's not a problem.

Phonegap+Ember+jQuery+Bootstrap accessing button through jQuery?

I've built an Ember.JS app using the latest Bootstrap.css/js for styling. In one of my templates, I have a button that triggers an action that disables the button and sets it's text to "loading" via the Bootstrap function described here. I access the button using jQuery from within my action as follows:
$('.find').button('loading'); //Starts "Please Wait" message
This worked great when running the ember app a server on my desktop. However, I'm presently trying to package the app into a Phonegapp app, initially in iOS. Whenever the action fires in the simulator, I get the following error:
I'm beginning to suspect this may be due to my action-firing button not being accessible through the class with jQuery like on desktop? But I'm not terribly sure as this is my first Phonegap app. Many thanks if someone can clear this up.
Got it! It was solved by an answer on this question.
I don't think that JQuery is being loaded into the page.
You have referenced it as:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js">
which says use whatever protocol the current page is being server
from. On a mobile device you are being served from file:// so the
actual request the browser makes to fetch the script is:
file://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js
You need to specify the scheme you want to use or else include it in
the PG project itself.
With me, it wasn't my jQuery not being loaded, but rather my Bootstrap.js! When you follow the CDN instructions on the bootstrap website, the URLs are similarly formatted starting with "//" (known as a "protocol-relative URL" or also "network-path reference") instead of the explicit "http://". Making the changed fixed the issue!

Categories