I have a form post method, which is used to show a new page. Its done this way so that the arguments used cannot be seen in the location bar.
Each window is given a unique name, but I want to be able to detect if this browser window is already open, so that calling this form again will not force that current browser window to auto-fresh.
Any suggestions?
I assume you're opening new windows in Javascript. So, assign a variable name to your new window (e.g. var newWin1 = window.open(...))
Then test to see if the document of your window exists:
if(newWin1.document) { alert("Window is open!"); }
else { alert("Window is gone!"); }
For a security note: people can still see the post data you're sending with any HTTP header tool. Check out LiveHTTPHeaders for Firefox (or a million others) to see what I mean.
Another note: Not sure what you're doing, but people don't like when a webpage does things without them asking it to (like opening windows). You may want to consider improving your design to a more user-friendly method.
Related
I dont really unterstand how the Chrome Extension API works. It was a rough to understand how the background.js and the content.js works, but my current Problem is, that the function insertCSS(); seems to need the tabId, even if the official documentation says that its optional.
So, none of the Answers on this plattform could help me, because I dont even understand the Concept of the whole API.
So can anybody explain me, why something like this is not possible?
var tabInfo = chrome.tabs.getCurrentTab();
var id = tabInfo.tabId;
There are several questions to be answered here.
Literal question
So can anybody explain me, why something like this is not possible?
var tabInfo = chrome.tabs.getCurrentTab();
Short answer: because most of the Chrome API does not return a value; it is asynchronous, meaning that some other component of Chrome will work on getting the answer while JS execution resumes.
A comprehensive overview of JS asynchronicity can be read at this canonical question.
There are two ways to deal with it:
Use callbacks, and be aware that the actual callback execution happens after the rest of the calling code.
Use async/await and/or Promises. The WebExtension polyfill can help with that, but it's outside the scope of the question.
Question in title
Simplest Way to get the current Tab Id?
or "why chrome.tabs.getCurrentTab won't help you".
chrome.tabs.getCurrentTab() returns the tab ID of the calling page. See the docs.
This is of limited utility: only extension pages (and not content scripts) can call this API.
Extension pages are:
background (no tab ID),
popup (no tab ID),
options page (it's complicated as it's embedded in a Chrome page),
"other" extension pages opened in a visible tab (here, it works as expected).
It's not your use case, as established in the comments.
The actual way to get the current active tab is chrome.tabs.query() with the query {active: true, currentWindow: true}, but keep on reading.
Actual question you're having
As reconstructed from the comments, here's the actual scenario you're having:
I have an event in a content script. I need to call the tabs.insertCSS API, so I'm messaging the background page to do it for me. How do I get the tabId for this call?
Well, the key here is to take a closer look at the runtime.onMessage event listener signature:
The callback parameter should be a function that looks like this:
function(any message, MessageSender sender, function sendResponse) {...};
What's a MessageSender?
An object containing information about the script context that sent a message or request.
tabs.Tab (optional) tab
The tabs.Tab which opened the connection, if any. This property will only be present when the connection was opened from a tab (including content scripts), and only if the receiver is an extension, not an app.
[...]
Jackpot. We're sending the message from a content script, and the listener is handed the sender.tab information "for free". We just need a quick detour into tabs API docs to see what a Tab contains, and we have it:
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
chrome.tabs.insertCSS(sender.tab.id, {/*...*/});
});
Misconception
my current Problem is, that the function insertCSS() seems to need the tabId, even if the official documentation says that its optional
It doesn't. If you call it omitting the tabId, which makes the details object the first argument, then Chrome will assume you want the "the active tab of the current window".
It may seem that this doesn't work if you're trying to execute it in the Dev Tools window for the background page. That's because in this instance there's no such tab. The current window is the one you're putting the console command in. So what the call does without the tabId is very sensitive to what actually is the current window.
It may also be the case that you don't have the permissions to inject in the current active tab, that would also fail.
Generally, it pays to be specific with the tab ID, it removes uncertainty about the logic of the extension.
I'm opening a window as
winRef = window.open(......);
Then I'm storing the above winRef in cookie so that I can get the reference to child window even if the parent refreshes.
That didn't work because when I tried to save winRef in cookie it just saves the text representation/string of the object so you only have "[object Window]" as string, it's not an object.
Is there any way to store the window reference as a cookie? If it's not possible then what are some other possible methods which I can use?
PS: I think storing just the window name instead of window object in the cookie can solve the issue but it can't be done in my case, I can't provide window names, basically the window is an online editor, if I give a particular name to it then user can't open multiple online editors as it will always reload the currently opened window.
Ultimate goal: Retrieving references to child window if the parent refreshes
First excuse me for my poor English ;-)
A possible workaround for this problem is to set a name in the window.open function (eg: popup = window.open(URL, popup_window, specs, replace)
Then save popup in a cookie.
When retrieving the cookie, you'll get the [object Window] as you said.
eg: popup = getCookie('popup');
After just do the following :
if (popup == null) {
//No popup
} else {
//Popup exist, retrieving is ref
popup = window.open("" ,"popup_window");
}
Just reuse the window.open function, just with the same name (popup_window) and no other arguments, as this window already exist no further actions will be performed just returning the popup_window ref.
Variables are abstractions that live on primary memory (aka RAM) and in the scope of a running process or thread. You just can't store them anywhere else.
Particularly, cookies are plain text. They are sent as HTTP headers and they're often stored in text files. So to answer your question: no, you cannot store a JavaScript object of type window in a cookie.
I open a new window to a Google docs presentation using the method window.open :
NewWindow = window.open("https://docs.google.com/presentation/d/1Qs9......");
I want to retrieve that url in order to know of it has changed (each slide of the presentation has a different url and i want to see if the user changed slides), using NewWindow.location.href
All i get is an undefined value. I can change href though
NewWindow.location.href ="http://www.google.com"; //works
I've read that if you are not in the same domain, you are not allowed to access the href or any other properties on the remote window.
Isn't there any other way to do it?
Thanks in advance.
There is a workaround but not in JavaScript.
The standard solution is to map the documents into your own domain using a proxy server that runs hidden under some URL of your own domain.
That way, you can access the documents via https://your.doma.in/google/presentation/...
A word of warning: If you make a mistake with configuring the proxy, crackers can abuse it to do nasty things (like trying to hack Google or send spam; the police will come knocking on your door).
I am not sure how to get by this one. I am using openId with the dotnetopenauth library.
I have some predefined provider that when clicked does a jquery post to the server and does a request to the provider.
I get the url back from provider and I do window.open(....) and open it as a new window with a predefined height and width.
Now they log in and do all that great stuff. Now the provider sends me their information to a controller method that I specified.
Now after I authenticate them I want to go to a new page. However I want to the page to open in the main window and no the window that I opened with window.open(). I want that closed and gone.
I can't get it to work. It will just start using that window.open() window to load all the pages in and I don't want that.
So I no clue what to do.
You just need to keep a reference to the first window around:
var oauthWindow = window.open(....);
later:
oauthWindow.close();
It's a complicated piece of work to get right, to be sure.
A couple of good examples are:
NerdDinner (source)
DotNetOpenAuth ASP.NET MVC 2 project template
I am opening a window and passing set of parameters to it. In this case, I am sending json string. At time, the info is toolarge, and Request-URI Too Large occurs.
window.open('../pssops21/php/createPhonePdf.php?strSelectedItems='
+ strSelectedItems + '&strQBNumbers=' + arrQBNumbers, 'mywindow',
'resizable=1, scrollbars=1, left=80,top=60, width=650, min-height=400')
Window.open does not have option to post. Jquery ajax only posts info retrieves, results and does not open a new window.
Are there any methods to do this?
Thanks.
Unfortunately this is tricky situation in web applications. The limit on the size of a URI is typically dictated by the browser you are using and the option to POST data is not a standard available. As for doing an Ajax post and then "loading" the results, is typically not supported for security reasons.
A workaround I have used in the past is to make it a two-step process. Basically use Ajax to post your json data to the server. As a response, have the server send back some kind of token to retrieve the stored data. Then, use that token as a parameter to the new window you are opening, who can then retrieve the data.
I know it is a little bit more work to get the data over to your new page, but it does eliminate these size/security restrictions, and is a cross-browser safe.
You could open a new window to a temporary page, then POST from that page in the new window using a form filled out by JavaScript in the original page.
You could use a hidden form that has your destination page as its target. Use hidden fields for your post values, and submit the form using the Javascript submit() method.
I believe this will only work if you're trying to redirect the current window, not open a popup, although there may be a way around that restriction as well.
Rather than embedding information to pass to the window in the querystring, you can use javascript directly. Using window.opener on the newly opened window, you can access info from the child page:
var selItems = window.opener.strSelectedItems;
Keep in mind that strSelectedItems in this case would need to be globally scoped in the parent page. To keep things clean, I would consider functions on the main page that will return the information the child page needs.