Let's say normally my users access our web page via https://www.mycompany.com/go/mybusinessname
Inside this web page, we have a iframe which actually comes from https://www.mycompany.com/myapp
Everything is working fine, except that if for some reason, the users come to know about this url https://www.mycompany.com/myapp. They can start accessing it directly by typing into the address bar.
This is what I want to prevent them from doing. Is there any best practice to achieve this?
==== Update to provide more background ====
The parent page which is https://www.mycompany.com is the company's page and it's maintained by some other team. So they have all the generic header and footer, etc. so each application is rendered as an iframe inside it. (This also means we cannot change the parent page's code)
If users access https://www.mycompany.com/myapp directly, they won't be able to see the header and footer. Yes, it's not a big deal, but I just want to maintain the consistency.
Another of my concern is that, in our dev environment (aka when running the page locally) we don't have the parent-iframe thing. We access our page directly from http://localhost:port. Hence I want to find a solution that can allow us access it normally when running locally as well.
If such solution simple does not exist, please let me know as well :)
On your iframe's source, you can check the parent's window by using window.top.location and see if it's set to 'https://www.mycompany.com/go/mybusinessname'. If not, redirect the page.
var myUrl = 'https://www.mycompany.com/go/mybusinessname';
if(window.top.location.href !== myUrl) {
window.top.location.href = myUrl;
}
I realized we already had a function to determine whether the page in running under https://www.mycompany.com. So now I only need to do the below to perform the redirecting when our page is not iframe
var expectedPathname = "/go/mybusinessname";
var getLocation = function (href) {
var l = document.createElement("a");
l.href = href;
return l;
};
if (window == window.top) { // if not iframe
var link = getLocation(window.top.location.href);
if (link.pathname !== expectedPathname) {
link.pathname = expectedPathname;
window.top.location.replace(link.href);
}
}
You can use HTTP referer header on server-side. If the page is opened in IFRAME - the referer contains parent page address. Otherwise, it is empty or contains different page.
Related
I have an iframe and I want to reload the currently displayed page on button press.
HTML:
<iframe id="webView"></iframe>
JS:
function reloadPage()
{
var webView = document.getElementById("webView");
//CODE
}
Inside the reloadPage() method I tried different solutions:
Call reload()
webView.contentWindow.location.reload();
This just doesn't work because the pages loaded inside the iframe are from a different domain than the main page.
Set src
webView.src = wevView.src;
It gives wrong result because it contains the initial url that I set to the iframe, non the current one.
Set location
webView.contentWindow.location = webView.contentWindow.location
I was expecting it to not work with urls from different domains (the same as calling reload()), but actually it works and also gives a good result.
Good but not perfect: the location object holds the current url but strips any parameter.
For example if the frame is currently displaying the following url:
http://www.myserver.com/thatsite/?page_id=11
the location object contains this url:
http://www.myserver.com/thatsite/
So this one works well as long as there are no parameters in the url.
Better solution?
I rely heavly on urls with parameters (mostly WordPress installations) so i need a way to keep them while reloading.
Anyone knows a solution to achieve this?
just not possible, see this thread:
Get current URL from IFRAME
and this one
How do I get the current location of an iframe?
Since setting location works, you could use location.search to retrieve the GET parameters and reconstruct the URL that way.
Example:
webView.contentWindow.location = webView.contentWindow.location + webView.contentWindow.location.search
I'm trying to load a page as an iframe and then extract some information from it.
function calleniro(who, where, announcementID){
var url = 'https://personer.eniro.se/resultat/'+who+'/'+where;
var frameid=announcementID.substr(0,7)
var iframe=$('<iframe />', {
src: url,
id: frameid
}).appendTo('body');
iframe.load(function (){
var frame = $('#'+frameid).contents;
console.log(frame)
});
}
the console.log($(frameid)) renders the iframe-node as desierd, when I add content it seems to be not find anyting
var frame = $(frameid).contents().find('body');
doesn't work either.
Due to the Same origin policy you cannot interact with content outside of your domain.
If your only intent is to load the page to get values from it (i.e not actually display the IFrame) you could simply $.get() the Eniro url to get the raw HTML response and then parse it from there. I think that should be possible with jQuery, might require some tinkering though :)
Update
As has been pointed out, the same origin policy applies to my solution as well (learning something new every day!), however it should be perfectly possible to apply the solution at the server instead
In my web app, a user can click an item in a list, and I modify the url in their browser:
<li>Horse</li>
<li>Cow</li>
<li>Goat</li>
function onListItemClicked() {
window.location.hash = item.name;
}
this will change the url in the user's browser to:
www.example.com#Horse
www.example.com#Cow
www.example.com#Goat
if I'm reading correctly, we can't get the # part of the url servlet-side, right? If the user copies and pastes the url from their browser to friend, it would be cool if I could generate the page already initialized with the item they clicked.
It looks like this is not possible, I'll have to load the appropriate page via javascript after the document finishes loading,
Thanks
No, you can't do this from the server side on. URL fragments are purely client side. You need to do this in the client side during page load.
window.onload = function() {
var hash = window.location.hash;
// Do your business thing here based on the hash.
}
Now that I discovered here that I can't write JavaScript within one page to enter form data on another external page, I'd like to do this with a browser-based bookmarklet instead.
I'm able to access the data on my original page with this bookmarklet code snippet:
javascript:var%20thecode=document.myForm.myTextArea.value;
If I open the external Web-based form manually in the browser, this code changes what's in the text box:
javascript:void(document.externalForm.externalTextArea.value="HELLO WORLD"));
And this bookmarklet code will open a new browser window with the external form:
javascript:newWindow=window.open("http://www.url.com","newWindow");if(window.focus){void(newWindow.focus());}
However, when I try to put these snippets together in a single bookmarklet to open the external form in a new window and change the data inside, I can't access any of the elements in newWindow. For example, this doesn't work to check the existing value of the text area in the new window
javascript:var%20newWindow=window.open("http://www.url.com","newWindow");if(window.focus){void(newWindow.focus());}window.alert(newWindow.document.externalForm.externalTextArea.value);
Once I use the bookmarklet code to open the new window as newWindow, I don't seem to be able to access the elements within that new window. Any suggestions what I'm missing? Thanks.
That's because the bookmarklet runs within the sandbox (the environment) of the current web page. Since you're not allowed to access (the DOM of) another page which doesn't have the same protocol, domain name and port, you're not able to access the document property of newWindow when protocols, domains and ports don't match. BTW, the same is true for accessing iframes on a page.
As you're talking about an “external form”, I guess you don't stay on the same domain. The other examples retrieve or manipulate data on the current page (at that moment) and won't error out.
Also see Same origin policy.
Update: About the Delicious (et al.) bookmarklet: its code actually reads:
(function () {
f = 'http://delicious.com/save?url=' + encodeURIComponent(window.location.href) + '&title=' + encodeURIComponent(document.title) + '&v=5&';
a = function () {
if (!window.open(f + 'noui=1&jump=doclose', 'deliciousuiv5', 'location=yes,links=no,scrollbars=no,toolbar=no,width=550,height=550'))
location.href = f + 'jump=yes'
};
if (/Firefox/.test(navigator.userAgent)) {
setTimeout(a, 0)
} else {
a()
}
})()
So, yes, the parameters are only transferred using a GET request.
Let's say I have a web page (/index.html) that contains the following
<li>
<div>item1</div>
details
</li>
and I would like to have some javascript on /index.html to load that
/details/item1.html page and extract some information from that page.
The page /details/item1.html might contain things like
<div id="some_id">
picture
map
</div>
My task is to write a greasemonkey script, so changing anything serverside is not an option.
To summarize, javascript is running on /index.html and I would
like to have the javascript code to add some information on /index.html
extracted from both /index.html and /details/item1.html.
My question is how to fetch information from /details/item1.html.
I currently have written code to extract the link (e.g. /details/item1.html)
and pass this on to a method that should extract the wanted information (at first
just .innerHTML from the some_id div is ok, I can process futher later).
The following is my current attempt, but it does not work. Any suggestions?
function get_information(link)
{
var obj = document.createElement('object');
obj.data = link;
document.getElementsByTagName('body')[0].appendChild(obj)
var some_id = document.getElementById('some_id');
if (! some_id) {
alert("some_id == NULL");
return "";
}
return some_id.innerHTML;
}
First:
function get_information(link, callback) {
var xhr = new XMLHttpRequest();
xhr.open("GET", link, true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
callback(xhr.responseText);
}
};
xhr.send(null);
}
then
get_information("/details/item1.html", function(text) {
var div = document.createElement("div");
div.innerHTML = text;
// Do something with the div here, like inserting it into the page
});
I have not tested any of this - off the top of my head. YMMV
As only one page exists in the client (browser) at a time and all other (virtual/possible) pages are on the server, how will you get information from another page using JavaScript as you will have to interact with the server at some point to retrieve the second page?
If you can, integrate some AJAX-request to load the second page (and parse it), but if that's not an option, I'd say you'll have to load all pages that you want to extract information from at the same time, hide the bits you don't want to show (in hidden DIVs?) and then get your index (or whoever controls the view) to retrieve the needed information from there ... even though that sounds pretty creepy ;)
You can load the page in a hidden iframe and use normal DOM manipulation to extract the results, or get the text of the page via AJAX, grab the part between <body...>...</body>¨ and temporarily inject it into a div. (The second might fail for some exotic elements like ins.) I would expect Greasemonkey to have more powerful functions than normal Javascript for stuff like that, though - it might be worth to thumb through the documentation.