I've uploaded two web resources, a.HTML and b.JS. In the HTML document I have a section where a script is executed (and it works as supposed to) upload loading into the IFRAME on my form.
Now, because of the size of the code, I feel the need to refactor it and I'd like to move out some of the methods from the script tag of my HTML web resource to a separate JS web resource.
At the first step I've set up the separate JS web resource as follows.
function test() { alert("Success."); }
From the script inside the HTML document I execute the following, getting an error as test seems not to be known to the page.
alert("Get ready for test...");
test();
alert("Did it work?");
I've added the JS web resource to the form and savepublished, of course. There's surprisingly little info on the subject out there. I've found those links but none of them matches exactly what I need and gives me no hint on how to approach the issue at hand.
This link resembles what I want to achieve but it's about calling JS from JS where both are web resources.
This link is diagonally opposite to what I want but I don't know how to reverse it from calling HTML from JS whre both are web resources.
What should I correct?
Calling a function in a javascript webresource, from an HTML webresource in Microsoft Dynamics CRM
CRM 2015
Javascript webresource:
function test() { alert("Success."); }
HTML webresource:
window.parent.test();
CRM 2016
They now load HTML webresources in an Iframe so you can't access external js files, but you can access the XRM object. So you can place the function on this object.
Javascript webresource:
Xrm.Page.test = test;
function test() { alert("Success."); }
HTML webresource:
window.parent.Xrm.Page.test();
Check the following assumptions that you did:
save the web resource?
publish all changes?
add the resource to the frame in the regarded entity?
name the function hazaa
call the correct name, i.e. parent.window.test()?
If yes to all of the above, do three things.
Contact Microsoft. You've just found a serious bug.
Watch out. There will be pigs flying very soon.
Get a coat. It's about to get much colder.
(By that, I mean that you surely have missed on something in the list I've provided and that you need not to contact Microsoft, pigs won't start to fly and the hell won't freeze over.)
I think your test() function is in scope of your html document's window.
and when you call it from inside the iframe's document, it searches for test() in its scope.
Try out
alert("Get ready for test...");
parent.window.test();
alert("Did it work?");
and in case the test() is defined in the iframe and you are calling it from the HTML document try this.
alert("Get ready for test...");
document.getElementById("iframeId").src ="javascript:test();"
alert("Did it work?");
Related
Heyo,
I'm trying to create a script that opens a URL and sign in using the given credentials.
Therefore I created this:
window.open("https://stackoverflow.com/users/login");
document.getElementById('email').value = "ThisIsMy#Email.com";
document.getElementById('password').value = "ThisIsMyPassword";
document.getElementById('submit-button').click();
But then I changed the code to wait for the page to load using window.onload:
window.open("https://stackoverflow.com/users/login");
window.onload = function() {
document.getElementById('email').value = "ThisIsMy#Email.com";
document.getElementById('password').value = "ThisIsMyPassword";
document.getElementById('submit-button').click();
}
However, this does not seem to work.
Therefore I added some console.log into my code to debug, like this:
console.log("starting")
window.open("https://stackoverflow.com/users/login");
console.log("page open")
window.onload = function() {
console.log("page loaded")
document.getElementById('email').value = "ThisIsMy#Email.com";
document.getElementById('password').value = "ThisIsMyPassword";
document.getElementById('submit-button').click();
console.log("signed in")
}
When I run the code in the console (Chrome/Firefox), I get back started and page open, but nothing else.
When I test the function isolated (i.e. the 3 different document.getElementById) it works just fine. Something must be wrong with the window.onload call?
From other sources here on StackOverflow I tried to use document.onload instead, and I also tried to use document.addEventListener('DOMContentLoaded', function() {...}, but none of these seems to be working either.
Does anyone have any suggestions?
#newbie
You simply can't access a cross origin page. What you are trying is only available to browser addons. And addons also require a specific permission granted by the user. For example the chrome permission to modify a webRequest: https://developer.chrome.com/docs/extensions/reference/webRequest/
window.open() returns the child window and this can be accessed IF it is about:blank or if the same-origin-rule applies (protocol, hostname and port - see pic below). Take a look at this fiddle it shows something similar to what you are trying. (CORS 1)
Here you can see which child windows you may have access to. This means modify it on the fly or override it's content/location completly.
The only method to communicate between two pages is: window.postMessage() and the window: Message-Event which provides an easy to use API for communication.
in your html page, in the script tag, where you call to your js page, add defer. like this:
<script src="your_script.js" defer></script>
I would like to remind you it is not a very good idea to use password credentials inside javascript since it is hard to protect from public appearance.
I believe you can solve this kind of problem with programs such as Python, C++ , maybe Java , but Javascript is a Client-Side program which has some limitations but if you ask me these limitations actually makes it quite fun to use most of the time.
My addon uses a content script to interact with the page. But it also needs access to the page's javascript so it can run one of the page's routines. So my content script needs access to the page's script context.
Here's what I mean.
Addon uses main.js which access content.js and uses messaging to communicate.
But the web-page (into which content.js is being injected) has it's own javascript. My content.js needs access to that context so it can fetch the values from variables there.
How can one get that?
I have been reading these mdn docs, but it seems like they are talking about an html page that you code yourself, like you would for a preferences page. But in my case I am working with an external website, not something coded just for the addon.
The approach listed on the MDN page also works for external pages, not just your own.
I.e. unsafeWindow.myPageVar will work.
This works:
var script = document.createElement("script");
script.innerHTML = "alert( myPageVar );";
document.body.appendChild( script );
Credit goes to this fellow.
I don't know whether this is the best way to do this, however. I hope that someone else more knowledgeable than me will answer.
Here's how to return a value:
var retval = unsafeWindow.SomePageFunction();
alert(retval);
It's called "unsafe" because you never know what about the page might be changed or might change. That's how it when the addon interacts with page scripts.
I have set up an Articulate Storyline course (a Flash version accessed using the page "story.html" and an HTML5 version accessed using "story_html5.html"). It works fine when run directly, however, when I try to run everything in an iframe on the company server (linking to the course files on my personal server) I get JavaScript errors:
The course uses player.GetVar("HTML5spelaren") to access a variable called HTML5spelaren, which is located on the story_html5.html page itself. When running in an iframe I get a "Permission denied to access property 'HTML5spelaren'".
Finally the course uses the JavaScript var newWin=document.window.open("report.html", "Kursintyg"); to display a course completion certificate in a new window. When running in an iframe however this results in a "Permission denied to access property 'open'".
Is there a way to rewrite the JavaScripts to get around this? I need to be able to detect if the course is running in Flash or HTML5 mode (that's what I use the variable in story_html5.html for), as well as being able to use JavaScript to open a new page from within the iframe when clicking on a link.
Page structure:
https://dl.dropboxusercontent.com/u/11131031/pagestructure.png
/Andreas
There's a way for different domains to speak to one another via javascript. You can use postMessage: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
In your case, in story.html or story_html5.html could use something like:
parent.postMessage(HTML5spelaren, parent_domain);
and you add an event listener in the company page:
window.addEventListener("message", receiveMessage, false);
And in receiveMessage function you retrieve the data that you need. Something like:
function receiveMessage(event){
your_variable = event.data
}
Same logic can be probably be applied to your popup.
You can post from child to parent or from parent to child.
My guess is that content you're linking to in the iFrame is on a different server/domain. If so, the error is a security feature to stop cross-site scripting (XSS) attacks.
Consider putting both the parent iFrame and the articulate content (child) on the same server. This should eliminate the problem.
I am looking for a way to modify an iFrame attribute (a textbox value actually). The iFrame is on another domain and I do have access to it. From what I understand I must do that after the entire page (iFrame included) is rendered. I tryed something like that:
<script type="text/javascript">
$(window).load(function() {
alert("test");
d = document.getElementById("myframe");
d.contentWindow.document.getElementById("frametxtbox");
});
</script>
But I always get the following error:
Cannot call method 'getElementById' of undefined
I also noticed that the alert pops up BEFORE the iFrame is rendered, so I think my script is executed before page has access to frame values and, therefore I get the error. I have very few knowledge of web-related programming (always worked on backend side) so forgive me if my question maybe makes no sense.
If the iframe points to another domain, it'll be subject to same origin policy. This means that before you try to access its document you'll have to check the wiki and relax the policy (check the link for details). After that you'll need to bind ready event to the iframes document, rather than your main page doc.
$(window.frames['myframe'].document).ready(function() { alert('moo'); });
See if this helps :)
After some research (even at stackoverflow) I still can't figure out how to do this. parent.method() won't do the trick, nor some other solutions I've tried.
Situation: I have a index.html on the client side (mobile phone in this case) which has an iframe loading server-side page. What I need to do is call a javascript method defined in the index.html (client side) from the iframe content (server-side).
As an example (I'm not using android in the question described above), Android apps have addJavascriptInterface which, when defined, allows one to call methods defined client-side from server-side pages just invoking window.CustomObject.MethodToCall().
Any hint?
Thanks!
window.top.foo
for the top level window
window.parent.foo
for the direct parent
I realize I am only a year late to this party but there was no real answer.
So, in order to do this both files must be on the same domain. Since you have the index.html on the phones localhost and load a page on your site it will not work (locahost to example.com). You could load the index.html off your site as well and that would fix this problem (example.com to example.com). Then you could reference the parent frame in the normal window.top.function.
In certain situation there could be a neccessity of calling a javascript function inside an iframe from the parent document, and vice versa ie;
calling a javascript function in parent document from the iframe.
For example; the parent document have an iframe with id attribute ‘iFrameId‘, and the function ‘functionInIframe()‘ is defined in that iframe document.
Following code can call that iframe function from the parent document itself.
document.getElementById('iFrameId').contentWindow.functionInIframe();
And following code can call the function defined in parent document(functionInParent()) from the iframe itself.
parent.functionInParent();
This way javascript can interact between parent document and iframe.
This is the original post.