I've run across some code that is using the following type of referrer hack to pass along referrer information to a popup window via Javascript in IE:
var targetName = "linkTarget";
_win = window.open("", targetName, 'width=800,height=480,resizable=yes,status=yes,location=yes,toolbar=no');
var _link;
if (!document.getElementById("referrerHackLink")) {
_link = document.createElement('a');
_link.id = "referrerHackLink";
document.body.appendChild(_link);
}
else {
_link = document.getElementById("referrerHackLink");
}
_link.target = targetName;
_link.href = url;
_link.click();
HTTP Referrer and IE7 and IE8
http://webbugtrack.blogspot.com/2008/11/bug-421-ie-fails-to-pass-http-referer.html
In an interesting twist, when I attempt to use that method with certain URIs (including localhost), IE9 and IE10 blur the popup window and navigate to the target URL in the main window.
You can find an example here:
http://jsfiddle.net/geoffreymoller/JKXzk/
Any ideas on why the localhost version might change the popup and target information like that?
_win = window.open("", targetName, 'width=800,height=480,resizable=yes,status=yes,location=yes,toolbar=no');
i think the window name in IE is limited to names like _self, _top, _blank, etc... as a result any name not like the expected list might be treated like _self
Related
I am trying to start a custom protocol handler in Chrome via Javascript. I can get the app to start but to do so creates a popup window which then triggers a pop-up blocker. Is there anyway to start the app without a pop-up window? The window closes but it is still considered a pop-up.
This is my current code:
function setBrowser() {
var userAgent = navigator.userAgent.toLowerCase();
if (userAgent.indexOf("chrome") > -1) {
//If Chrome launch without ActiveX involved
var url = 'ABCProcessLaunch:-Domain mydomain -Args http://google.com -requirelogin true -method "chrome"';
setTimeout(window.close, 10);
window.open(url, '_blank');
}
}
I'm inferring from your call to window.close that this is likely why you need to open the link in a new window in the first place.
You may have some luck with opening the custom URL scheme in an <iframe> element instead. That way, your setTimeout call will still be triggered after 10 seconds:
function setBrowser() {
var userAgent = navigator.userAgent.toLowerCase();
if (userAgent.indexOf("chrome") > -1) {
//If Chrome launch without ActiveX involved
var url = 'ABCProcessLaunch:-Domain mydomain -Args http://google.com -requirelogin true -method "chrome"';
var iframe = document.createElement("iframe");
iframe.src = url;
setTimeout(window.close, 10);
document.querySelector("body").appendChild(iframe);
}
}
I'm working on a phaser game that's to be embedded in a website via iframe. The game supports multiple languages, so we've taken to using the site the game was accessed from as an indicator (phaser-game.com/ru would be in Russian, phaser-game.com/ar would be in Arabic, etc).
Here's the code so far (fired via window.addEventListener('load', getDomainSetLanguage);:
function getDomainSetLanguage()
{
let url = (window.location !== window.parent.location) ? document.referrer : document.location.href;
console.log('url = ' + url);
for (let i = 0; i < COUNTRIES_DOMAIN.length; i++)
{
if (url.indexOf(COUNTRIES_DOMAIN[i].URL) >= 0)
{
DOMAIN_ID = COUNTRIES_DOMAIN[i].ID;
LANGUAGE_ID = COUNTRIES_DOMAIN[i].LANGUAGE_ID;
break;
}
}
if (DOMAIN_ID === -1)
{
DOMAIN_ID = 1;
}
if (LANGUAGE_ID === -1)
{
LANGUAGE_ID = 1;
}
console.log('DOMAIN_ID = ' + DOMAIN_ID + "; LANGUAGE_ID = " + LANGUAGE_ID);
}
Now this works fine, on the surface. However, the game does trigger a reload every now and then, and when the game comes back, it now gets it's own URL, not the parent's / iframe's.
This has the result of the game language defaulting to English.
Note that this only occurs in Chrome and Safari. FireFox works just fine.
Is there something I'm missing? Or is there anything else I can try?
I've tried logging the values of document.referrer and document.location.href, but I'm just getting browser errors about permissions and stuff and the game defaults to English.
I read from here that Chrome (and possibly Safari) doesn't fire the onload function of objects in the iframe, but I'm not sure if this applies to me, as I have a lot of other functions tied to onload that do work.
It should be mentioned that I cannot modify the iframe itself, so any solution must be from the game itself.
Thanks!
let url = (window.location !== window.parent.location) ? document.referrer : document.location.href;
This line from your code makes it so that when you're inside of an iframe, document.referrer is used as the URL to determine the language from.
As per the MDN page on Document.referrer:
The Document.referrer property returns the URI of the page that linked to this page.
Inside an <iframe>, the Document.referrer will initially be set to the same value as the href of the parent window's Window.location.
This means it will work on initial load just fine, as you've experienced.
As far as I can tell, the specification isn't explicit about how to handle reloading. This is probably the cause of the differences in browser behaviour. It isn't too crazy to think that is should be empty after a reload, as it wasn't loaded from the parent page that time around.
An alternate solution would be to use window.parent.location.href, which always refers to the URL of the iframe's parent window (read more in Difference between document.referrer and window.parent.location.href).
Your line of code could look something like this:
// if parent and child href are equal, using either yields the same result
// if there is no parent, window.parent will be equal to window
// therefore, the conditional statement isn't necessary
let url = window.parent.location.href;
Below is my code.
It is resulting in unexpected behaviour.
It navigates to bing.com but it does not fill in the text field. Also, I have noticed that the console get cleared after navigating to a new webpage.
window.location = "https://www.bing.com";
window.onload = function(){
var editSearch = document.getElementById("sb_form_q");
editSearch.value = "Quux";
}
You are binding the onload function to the existing window object.
When the browser loads the new page, it will make a new window object which won't have your property set on it.
JavaScript run in one page (even when you are running it through developer tools) can't persist variables onto a different page.
(Storage mechanisms like localStorage and cookies are available, but you would need code in the subsequent page to look for them).
JavaScript is only valid for the current page you are on. When you are executing code from DevTools console, you are executing code on that page itself. So, when you navigate to another page using window.location you loose the onload handler you have defined.
To add handlers to a different page, it must be connected to your page (the parent) in some way, like an iframe or a popup.
ifrm = document.getElementById('frame');
ifrm.src = 'http://example.com';
ifrm.contentWindow.onload = function () {
// do something here with
// ifrm.contentWindow.document.getElementById('form')
}
As #Quentin said.
But you can do another way like ..
var keyword = "Quux";
window.location = "https://www.bing.com/search?q="+keyword;
I want to open a new tab when a user clicks on a link. The link is user generated and when users enter a url like www.google.com the tab doesn't work as expected. This is a jsFiddle to show the problem and this is the code:
open new tab
How can I fix this? Telling users to enter a well-formed URL is not an option.
Don't Forget The Protocol
The window.open() function expects the appropriate protocol to be present when requesting the URL (i.e. http://, ftp://, https://, etc.), so you'll need to ensure that you include this to work properly :
window.open('http://www.google.com');
Manually Prepending The Protocol
If you need to explicitly omit the protocol for whatever reason, you could consider writing a function to handle opening your window for you :
function openWindowAndPrependProtocol(url){
if(/^https?:\/\//i.test(url)){
// If it doesn't start with http:// or https://, then append it
return window.open('http://' + url);
}
}
which would change your code to use :
var a = openWindowAndPrependProtocol('www.google.com');
Note
According to Mozilla, they generally don't recommend using links in this manner to open new windows via window.open() if at all possible, as it can bring about some usability concerns. Their best practices recommends using an external function similar to the second approach to handle opening the window.
If you want to add a protocol automatically to an URL, which a user of your page provided, you can do this with the following function:
JavaScript (needs be added somewhere on your page):
<script type="text/javascript">
function openURL(url) {
var allowedProtocols = ["http://", "https://", "ftp://", "ftps://"];
var hasPrefix = false;
for(var i = 0; i < allowedProtocols.length; i++) {
if(url.substring(0, allowedProtocols[i].length) === allowedProtocols[i]) {
hasPrefix = true;
break;
}
}
if(!hasPrefix) {
url = "http://" + url;
}
window.open(url);
}
</script>
HTML:
<a onclick="openURL('www.google.com')">Google</a>
Try this:
<a onclick="window.open('https://www.google.com', 'Google', 'width=800,height=800')">
It opens in a new tab and 800×800 are the dimensions of the window.
You need to add a protocol like http:// or https://
open new tab`
My script opens a new window and then writes its content. The destination window displays "Hello World" as expected, but the URL is the same as the window that the script ran in and I don't understand why.
Is there a way to build a new window without picking up the old URL?
function doTest() {
var impl = document.implementation;
var tempDoc = impl.createHTMLDocument("Hello");
var tempBody = tempDoc.getElementsByTagName("body")[0];
var tempDiv = tempDoc.createElement('div');
var tempMsg = tempDoc.createTextNode('Hello World.');
tempDiv.appendChild(tempMsg);
tempBody.appendChild(tempDiv);
var destWindow=window.open("about:blank", "title", null, false);
var destDoc=destWindow.document;
destDoc.open();
destDoc.write("<html>"+tempDoc.documentElement.innerHTML+"</html>");
destDoc.close();
}
var btnTest = document.createElement( 'input' );
btnTest.setAttribute( 'value', 'Test' );
btnTest.setAttribute( 'type', 'button' );
btnTest.addEventListener('click',doTest,true);
document.body.appendChild( btnTest );
I'm using Firefox 20 and Greasemonkey 1.8.
I don't think you can do this. This is probably a security feature; see Bug 337344, "Disable location bar hiding by default, to make chrome spoofing harder" and related bugs.
I think that as soon as parent-window javascript tries to alter the content, then the anti-spoofing protection forces the location to the opener's URL. This is true even if you open the window with a URL other than about:blank.
You can hide the location bar by change the setting dom.disable_window_open_feature.location to true in about:config and then hide the address bar by passing location=false in window.open.
But if you do, then the opener's URL will be prepended to the title bar.
You'll probably have to live with this and be grateful that phishing is that much harder. ;-) Or, if you can make a compelling case for why you should be able to alter or blank the location: (1) add it to your question and (2) open a bug or feature request with Mozilla.
Workaround:
You can set your script to also fire on about:blank, and then have GM make the page from the blank instance, not the opening instance. See this answer for an almost identical scenario/solution.
Be sure to open the window with an explicit about:blank, like so:
var destWindow = window.open("about:blank", "title", null);