I'm adding a script tag to a web page once it's fully loaded in a WebEngineView, but it's silently failing somehow.
I inject the script by invoking webview.runJavaScript with this code:
var s = document.createElement('script');
s.src = "qrc:/jquery-2.1.4.min.js";
document.body.appendChild(s);
That's perfectly standard and to a certain extent it works as expected, i.e., if I view the html source of the page, the script tag has indeed been appended to the body.
The problem is that the script isn't being downloaded, or isn't being evaluated, or something. All I know is in the above example the jQuery functions aren't available. If I load a small JavaScript test file with one global variable, that variable's not available either. Changing the url to http instead of qrc and pointing it to a web server makes no difference.
Injecting an img tag works fine; the image is loaded and displayed.
But JavaScript is broken somehow. Does anyone know how to fix this?
The problem had to do with the asynchronous nature of QML and JavaScript.
I was inserting a script tag to inject jQuery, and then I was calling a function to de-conflict my inserted version of jQuery from whatever version of jQuery might already be in the original page.
But I believe the webview had not finished parsing the inserted jQuery library before my de-conflicting function was called, so it failed. (I'm not very experienced with browser programming or I might have suspected this from the beginning.)
The solution was to insert a script tag with a small bit of JavaScript that inserts jQuery and then sets a timeout to wait 200ms before calling the de-conflict function. Like so:
function insertAuhJQuery(){
var s = document.createElement("script");
s.src = "qrc:/jquery-2.1.4.min.js";
document.body.appendChild(s);
window.setTimeout(deConflictJQuery, 200);
}
function deConflictJQuery(){
auh = {};
auh.$ = jQuery.noConflict(true);
}
insertAuhJQuery()
That works reliably and is acceptable for my purpose.
I have an IndexedDB database with html documents stored inside as blobs and a webapp using an iframe to visualize these documents.
My problem is : I want to get the store of the database where are the html documents everytime I click on a link inside a html document displayed inside the iframe, but it throw an exception when I try. When I'm not "inside" the iframe(the function is inside an eventListener bind to a hypertext link inside the iframe), it gets it without any problem.
The function used is :
function getObjectStore(store_name, mode) {
var tx = db.transaction(store_name, mode); // mode in this case is 'readonly'
return tx.objectStore(store_name); // line where the exception is thrown when "inside the iframe"
}
where db is my database. The exception thrown is :
Exception... "A mutation operation was attempted on a database that did not allow mutations." code: "11" nsresult: "0x80660006 (InvalidStateError)"
Because everything's all right with other cases and that I don't see any problem in the steps of getting my store, I wanted to know if I have this problem because I can't reach the database of the main window even if the main page and the page in the iframe are from my local server, or because another reason.
Thank you for your advice !
Indexeddb doesn't run inside an iframe deu security risks.
The exception youbare talking about means you are trying to add, edit or delete data in an object store using a readonly transaction. If you want to manipulate data use a readwrite transaction.
Known issue - Third-party databases are not visible.
For example, if you use an iframe to embed your page while using IndexedDB, your page's IndexedDB data won't be visible.
See issue #943770:
Issue 943770: DevTools: Show iframe IndexedDB databases
Workaround - one option is to open the iframe page directly and observe the indexeddb related to the site - instead of working through the iframe container page.
I am programming in Visual Foxpro. I tried to programatically .click() at the submit button. It used to work, but now it triggers nothing. Alternatively I tried to .submit() the form. This too triggers nothing. But if I click the submit button at the website, it works perfectly. Can anyone help me out? arunkasi.co#gmail.com
My coding as as follows:
declare Sleep in kernel32 integer nmilliseconds
WebMain = CREATEOBJECT("InternetExplorer.application")
WebMain.navigate("https://epayment.hasil.gov.my/fpx/one.php")
WebMain.visible = .t.
DO WHILE WebMain.busy .OR. WebMain.readystate#4
Sleep(300)
ENDDO
WebMain.Document.Forms("LogonForm1").jenis_id.selectedindex = 1
WebMain.Document.Forms("LogonForm1").no_id.Value = "123456781234"
WebMain.Document.Forms("LogonForm1").kapca.Value = "56789"
WebMain.Document.Forms("LogonForm1").cmdSubmit.click() && IT DOES NOT WORK !
WebMain.Document.Forms("LogonForm1").Submit() && ALTERNATIVELY, THIS TOO DOES NOT WORK !
Most likely cause of your change in behavior is an update to Internet Explorer, wherein they improved the security model to keep malicious websites from injecting unwanted behavior into them.
See if the website you are attempting to reach has an actual web service that applications can use to send POST messages via HTTP instead of using a web page, (such as using the MSXML.XMLHTTPRequest object). If that website is your company's, creating a proper web service is a far better use of time than automating internet explorer through FoxPro.
But, if that's not possible, I believe you can adjust your code to use the IE-specific fireEvent method.
Add a parameter to click() or submit(). This will work:
WebMain.Document.Forms("LogonForm1").cmdSubmit.click(1)
or
WebMain.Document.Forms("LogonForm1").Submit(1)
I've got a webpage I want to hook in to my Adobe Air app. It's running JavaScript, so I can't open it in the app, but I'm trying to launch it in the default system browser.
Here's the code that's supposed to be launching the page:
public function beginModule():void {
var loader:HTMLLoader = new HTMLLoader();
var gameURL:URLRequest = new URLRequest("file:///path/to/file.html");
loader.navigateInSystemBrowser = true;
loader.load(gameURL);
}
I've also tried using
flash.net.navigateToURL(gameURL);
but that had no effect.
Every time I hit the above method, that block executes but nothing happens other than a quick cursor change-- no browser opened, no change in the app. What am I missing here?
Before you start, check if the HTML page is properly running in the browser.
To open a HTML page in flex, use the HTML tag: <mx:HTML></mx:HTML>
Something like this: https://snipt.net/anishnair/flex-show-html-page/?key=28838d54ac287180032dee000ce33a74
Thank you.
Regards,
Anish
Simply use :
navigateToURL(url,"_blank");
to navigate to the url in the web-browser.
I have built a basic data entry application allowing users to browse external content in iframe and enter data quickly from the same page. One of the data variables is the URL.
Ideally I would like to be able to load the iframes current url into a textbox with javascript. I realize now that this is not going to happen due to security issues.
Has anyone done anything on the server side? or know of any .Net browser in browser controls. The ultimate goal is to just give the user an easy method of extracting the url of the page they are viewing in the iframe It doesn't necessarily HAVE to be an iframe, a browser in the browser would be ideal.
Thanks,
Adam
I did some tests in Firefox 3 comparing the value of .src and .documentWindow.location.href in an iframe. (Note: The documentWindow is called contentDocument in Chrome, so instead of .documentWindow.location.href in Chrome it will be .contentDocument.location.href.)
src is always the last URL that was loaded in the iframe without user interaction. I.e., it contains the first value for the URL, or the last value you set up with Javascript from the containing window doing:
document.getElementById("myiframe").src = 'http://www.google.com/';
If the user navigates inside the iframe, you can't anymore access the value of the URL using src. In the previous example, if the user goes away from www.google.com and you do:
alert(document.getElementById("myiframe").src);
You will still get "http://www.google.com".
documentWindow.location.href is only available if the iframe contains a page in the same domain as the containing window, but if it's available it always contains the right value for the URL, even if the user navigates in the iframe.
If you try to access documentWindow.location.href (or anything under documentWindow) and the iframe is in a page that doesn't belong to the domain of the containing window, it will raise an exception:
document.getElementById("myiframe").src = 'http://www.google.com/';
alert(document.getElementById("myiframe").documentWindow.location.href);
Error: Permission denied to get property Location.href
I have not tested any other browser.
Hope it helps!
document.getElementById('iframeID').contentWindow.location.href
You can't access cross-domain iframe location at all.
I use this.
var iframe = parent.document.getElementById("theiframe");
var innerDoc = iframe.contentDocument || iframe.contentWindow.document;
var currentFrame = innerDoc.location.href;
HTA works like a normal windows application.
You write HTML code, and save it as an .hta file.
However, there are, at least, one drawback: The browser can't open an .hta file; it's handled as a normal .exe program. So, if you place a link to an .hta onto your web page, it will open a download dialog, asking of you want to open or save the HTA file. If its not a problem for you, you can click "Open" and it will open a new window (that have no toolbars, so no Back button, neither address bar, neither menubar).
I needed to do something very similar to what you want, but instead of iframes, I used a real frameset.
The main page need to be a .hta file; the other should be a normal .htm page (or .php or whatever).
Here's an example of a HTA page with 2 frames, where the top one have a button and a text field, that contains the second frame URL; the button updates the field:
frameset.hta
<html>
<head>
<title>HTA Example</title>
<HTA:APPLICATION id="frames" border="thin" caption="yes" icon="http://www.google.com/favicon.ico" showintaskbar="yes" singleinstance="no" sysmenu="yes" navigable="yes" contextmenu="no" innerborder="no" scroll="auto" scrollflat="yes" selection="yes" windowstate="normal"></HTA:APPLICATION>
</head>
<frameset rows="60px, *">
<frame src="topo.htm" name="topo" id="topo" application="yes" />
<frame src="http://www.google.com" name="conteudo" id="conteudo" application="yes" />
</frameset>
</html>
There's an HTA:APPLICATION tag that sets some properties to the file; it's good to have, but it isn't a must.
You NEED to place an application="yes" at the frames' tags. It says they belongs to the program too and should have access to all data (if you don't, the frames will still show the error you had before).
topo.htm
<html>
<head>
<title>Topo</title>
<script type="text/javascript">
function copia_url() {
campo.value = parent.conteudo.location;
}
</script>
</head>
<body style="background: lightBlue;" onload="copia_url()">
<input type="button" value="Copiar URL" onclick="copia_url()" />
<input type="text" size="120" id="campo" />
</body>
</html>
You should notice that I didn't used any getElement function to fetch the field; on HTA file, all elements that have an ID becomes instantly an object
I hope this help you, and others that get to this question. It solved my problem, that looks like to be the same as you have.
You can found more information here: http://www.irt.org/articles/js191/index.htm
Enjoy =]
I like your server side idea, even if my proposed implementation of it sounds a little bit ghetto.
You could set the .innerHTML of the iframe to the HTML contents you grab server side. Depending on how you grab this, you will have to pay attention to relative versus absolute paths.
Plus, depending on how the page you are grabbing interacts with other pages, this could totally not work (cookies being set for the page you are grabbing won't work across domains, maybe state is being tracked in Javascript... Lots of reasons this might not work.)
I don't believe that tracking the current state of the page you are trying to mirror is theoretically possible, but I'm not sure. The site could track all sorts of things server side, you won't have access to this state. Imagine the case where on a page load a variable is set to a random value server-side, how would you capture this state?
Do these ideas help with anything?
-Brian J. Stinar-
Does this help?
http://www.quirksmode.org/js/iframe.html
I only tested this in firefox, but if you have something like this:
<iframe name='myframe' id='myframe' src='http://www.google.com'></iframe>
You can get its address by using:
document.getElementById('myframe').src
Not sure if I understood your question correctly but anyways :)
You can use Ra-Ajax and have an iframe wrapped inside e.g. a Window control. Though in general terms I don't encourage people to use iframes (for anything)
Another alternative is to load the HTML on the server and send it directly into the Window as the content of a Label or something. Check out how this Ajax RSS parser is loading the RSS items in the source which can be downloaded here (Open Source - LGPL)
(Disclaimer; I work with Ra-Ajax...)
Ok, so in this application, there is an iframe in which the user is supplied with links or some capacity that allows that iframe to browse to some external site. You are then looking to capture the URL to which the user has browsed.
Something to keep in mind. Since the URL is to an external source, you will be limited in how much you can interact with this iframe via javascript (or an client side access for that matter), this is known as browser cross-domain security, as apparently you have discovered. There are clever work arounds, as presented here Cross-domain, cross-frame Javascript, although I do not think this work around applies in this case.
About all you can access is the location, as you need.
I would suggest making the code presented more resilitant and less error prone. Try browsing the web sometime with IE or FF configured to show javascript errors. You will be surprised just how many javascript errors are thrown, largely because there is a lot of error prone javascript out there, which just continues to proliferate.
This solution assumes that the iframe in question is the same "window" context where you are running the javascript. (Meaning, it is not embedded within another frame or iframe, in which case, the javascript code gets more involved, and you likely need to recursively search through the window hierarchy.)
<iframe name='frmExternal' id='frmExternal' src='http://www.stackoverflow.com'></frame>
<input type='text' id='txtUrl' />
<input type='button' id='btnGetUrl' value='Get URL' onclick='GetIFrameUrl();' />
<script language='javascript' type='text/javascript'>
function GetIFrameUrl()
{
if (!document.getElementById)
{
return;
}
var frm = document.getElementById("frmExternal");
var txt = document.getElementById("txtUrl");
if (frm == null || txt == null)
{
// not great user feedback but slightly better than obnoxious script errors
alert("There was a problem with this page, please refresh.");
return;
}
txt.value = frm.src;
}
</script>
Hope this helps.
You can access the src property of the iframe but that will only give you the initially loaded URL. If the user is navigating around in the iframe via you'll need to use an HTA to solve the security problem.
http://msdn.microsoft.com/en-us/library/ms536474(VS.85).aspx
Check out the link, using an HTA and setting the "application" property of an iframe will allow you to access the document.href property and parse out all of the information you want, including DOM elements and their values if you so choose.