Is there a way to open a Google Chrome plugin's options.html page via Javascript in background.html?
There is a new method that is enabled beginning with Chrome 42:
chrome.runtime.openOptionsPage(function callback)
Open your Extension's options page, if possible.
The precise behavior may depend on your manifest's options_ui or options_page key, or what Chrome happens to support at the time. For example, the page may be opened in a new tab, within chrome://extensions, within an App, or it may just focus an open options page. It will never cause the caller page to reload.
If your Extension does not declare an options page, or Chrome failed to create one for some other reason, the callback will set lastError.
chrome.tabs.create({ url: "options.html" });
Update
Starting with version 40, Chrome now uses a new popup options dialog from the extension management page instead of dedicated options pages (which are being deprecated). You can still achieve the same effect with a modification to the URL.
chrome.tabs.create({ 'url': 'chrome://extensions/?options=' + chrome.runtime.id });
Open or switch to already opened options page (instead of opening a duplicate):
var optionsUrl = chrome.extension.getURL('options.html');
chrome.tabs.query({url: optionsUrl}, function(tabs) {
if (tabs.length) {
chrome.tabs.update(tabs[0].id, {active: true});
} else {
chrome.tabs.create({url: optionsUrl});
}
});
Without using the Chrome API, only the standard Web APIs, the following is possible:
window.open("chrome-extension://ghipmampnddcpdlppkkamoankmkmcbmh/options.html")
Or, to navigate from a visible page to an extension page:
location.href = "chrome-extension://ghipmampnddcpdlppkkamoankmkmcbmh/options.html"
This requires hardcoding the extension ID.
Probably the only time this is preferable over using the Chrome API is when it's called from a non-extension context (and not the original "from background page" scenario). However, note that a web context cannot navigate to a chrome-extension://* page (it will result in about:blank) unless it's declared as web-accessible.
In such a scenario, one should also consider communicating with the webpage either through a content script or external messaging instead.
Related
Using: Manifest V3
How do I open my extension same way Metamask does it?
Currently what I have tried is that from my background service I am using chrome.runtime.sendMessage to send message to my content.html and .js of my extension where I have chrome.runtime.onMessage.addListener and listen for the open window message then I tried with chrome.extension.getViews({ type: 'popup' }).forEach(v => v.open()); to display my extension window, but instead it sometimes opens a new empty tab or sometimes I get error Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist.
What I want to accomplish is that the service worker which is constantly running in background, can open my extension window same way like when I click on extension icon.
Metamask case example: https://youtu.be/vhUjCLYlnMM?t=633
This:
From [ (Service worker) background.js ] open extension window programmatically, same way
as when clicked in the Chrome taskbar on the icon of extension.
You can open it with a new tab on the url in the css and js parts.
<a target="_blank" href="file.url"></a>
I had a similar situation but used a different tactic. Rather then relying on the content script, I am using the options page as the dispatcher.
I am not sure whether this helps in your situation, as I am not sure whether you want to open a new tab or a popup. This works for a new tab, but not for a popup.
Looking at chrome.runtime API, I found only one method that opens a new tab directly: chrome.runtime.openOptionsPage(). For this to work, you need to define an option page in your manifest:
{
"manifest_version": 3,
...
"options_ui": {
"open_in_tab": true,
"page": "options.html"
},
}
Note that the options page must be bundled with your extension. But if you open it in a tab, you can perform a redirect to wherever you want to be, for instance:
window.open("https://www.whereever.com","_self")
If you need to configure the destination, chrome.runtime.openOptionsPage() can take a callback function as an argument, which you can use on the options page to figure out the final destination page(s).
Below doesn’t work:
window.open(‘javascript:{do something here}’)
Some security error and asking for unsafe-inline keywordenter code here
I need to open a new window and navigate to a url and find a button and click it.
All i have are urls(hundreds of em) I’m looping and using promises for each url. The problem is the script doesn’t work because the page is reloaded as the link is clicked. Therefore it needs to be opened in new tab then I can run the script (of clicking button to download) as the link is opened.
var lk=[
{
"key": "www.someurl.com",
"value": "somefile"
},
{
"key": "someurl",
"value": "somefilename"
}];
p=Promise.resolve();
for(i=0;i<lk.length;i++){
p=p.then(new Promise(_=>{
var link = document.createElement("a");
link.download = lk[i].value;
link.href = lk[i].key;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
delete link;
setTimeout(()=>{
_();
},30000);
}));
console.log('Completed '+i);
}
Above script stops working as page is reloaded on link.click() in chrome console
I tried puppeteer, it has download issues. Any suggestions are appreciated.
Thanks
For security reasons, browsers isolate JavaScript code running on different origins (an origin is the combination of protocol, domain and port). While you can open a page on a different origin (by redirecting, opening a new window or adding a frame on the current page), you can't directly interact with it. So it's impossible for code on one page to open a different page and click on the button on that page.
The only way to work around this in a browser is to write a browser extension or user script. Browser extensions and user scripts are both higher privileged and able to interact with pages that are not under their control, but they need to be installed in the browser, and access to sites needs to be approved by the user (usually during installation).
I am creating another answer because you changed the question.
Don't create a link and then click on it, it will surely break the script due to reloading. instead, use ajax or https://www.npmjs.com/package/fetch. these will call the given URL in the background. but then you will not be able to click the button.
So I would suggest, you create an iframe with the URL, and then maybe try clicking the button.
If this would be possible, it would be a huge security issue. You could use it to lure somebody to your page, then open their online bank in new tab and make a transaction for example.
If you have control over the page you are opening in the new tab then you could pass some query parameter and listen to that parameter in the new page and invoke some javascript if this parameter is set.
If you want to run a script that will trigger a button on a new tab, and that tab is under your control, then you can achieve this by supplying your tab with the following script:
window.onload = function() {
document.getElementById('my-button').click();
}
I would suggest using Jquery Ready Function because it will be triggered once everything on the page is loaded.
Maybe open the URL into an Iframe and then you can control its content. Something like this: Control iframe content with javascript/html
Then you can not only click the button, but you have complete access to its DOM. but make sure X-Frame-Options is not set for that website. otherwise, this option will not work.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
and if that doesn't work:
Then you may want to try:
https://github.com/puppeteer/puppeteer
https://devexpress.github.io/testcafe/
https://www.cypress.io/
These tools are used for automated testing, but you can use these for your purpose.
These tools work like a human click on any button. They themselves open a browser, click on the button and let you know, or download the item or anything.
So, I've looked through the WebExtensions API, but I haven't been able to figure out how to open an HTML page separate from about:addons for options. In the Add-on SDK you could have resource://ext-id-/path/to/file.html. I've tried making a directory web accessible and putting an HTML file in there, but that didn't seem to work.
Does anyone know how I can open the options HTML file in it's own tab with WebExtensions?
Opening a tab
Options page always in a tab:
If you want your options page to always open in a tab, you can add the property open_in_tab with a value of true to the options_ui key in your manifest.json:
"options_ui" : {
"page": "options.html",
"open_in_tab":true
}
This will result in your options page always opening in a tab. Both clicking on your extension's "Options" from within about:addons and using runtime.openOptionsPage() will result in your options page opening in a tab.
Thanks to BigBlutHat for reminding me of this option.
In a tab when normally your options page is within about:addons:
You can open a new tab with whatever URL from within your extension you desire, including your options page, using tabs.create and runtime.getURL. Specifically for an options.html file located in the same directory as your manifest.json, the following works:
chrome.tabs.create({
url: chrome.runtime.getURL('/options.html')
});
Does not need to be web accessible and loading JavaScript:
You do not need the files to be declared as web accessible. The page runs in the background context so JavaScript is loaded by directly including the files in the src of a <script> tag (e.g. <script src="/options.js">). This is the same as you would do for a popup. This answer has an extension that uses the same HTML and JavaScript as both a popup and an options page. It does not, however, actually show opening that page as a tab, but it could be done with the above code.
Resolving Relative URLs:
Both Chrome and Firefox state:
Relative URLs will be relative to the current page within the extension.
Note: For all the different chrome.* API calls, Chrome and Firefox do not always resolve relative URLs in the same way. For example, it is different in each browser for chrome.executeScript().
Currently I have an application where a user hits a clicks on a URL and goes to my form. The user then enters his information into the form field, which is then sent through jquery ajax to a PHP script which enters it into the database. Upon success callback, it would alert the user that they had been registered and closes the current browser tab. (Let's just say I need the closing the browser tab behaviour to persist).
$.ajax({
type: "POST",
url: 'goToPHP',
data: data,
success: function(data){
alert('You Have Been Registered Successfully');
open(location, '_self').close();
},
error: function(data){
}
});
I understand that most modern browsers (Chrome included) are limiting the ability for javascript to only close tabs/windows it created for security reasons. Temporarily I had used open(location, '_self').close(); to get around the issue, but alas, it seems chrome's most recent update prevents you from doing this as well (Prompts you with a warning: 'Scripts may close only the windows that were opened by it'.)
Is there a way around this? I'm not talking about something along the lines of:
open(location, '_self').close();
But something that will work all the time on Chrome (e.g. changing a Chrome setting to allow scripts to close tabs/windows (similar to how this could be done through about:config in Firefox) or a way of restructuring how the user hits the form, so that the window object is available in javascript so i can call windowObject.close(); ) .
Thanks in Advance!
A browsing context is script-closable if it is an auxiliary browsing context that was created by a script (as opposed to by an action of the user), or if it is a top-level browsing context whose session history contains only one Document.
http://www.w3.org/html/wg/drafts/html/master/browsers.html#dom-window-close
In effect this means that, in common usage, you can only close windows/tabs that you have created in JavaScript. However, it is also possible to close a window or tab (but not a frame or other nested browsing context) as long as that window or tab has no history. Usually, this is a highly unreliable feature to make use of as you generally cannot realistically expect your user to have opened no documents in their browsing context before opening the one that you are trying to close; however, there are certain cases where you can safely assume that the page is in a context with no history, but generally these cases would fall under the 'opened by script' categorization as well.
Additionally, if you use a link to '#' for JavaScript purposes or any other sort of bookmark linking within your page, that will populate the session history and render the context unclosable unless you use JavaScript to prevent the hyperlink event from being executed. For purposes of JavaScript, it is probably better practice to just use javascript:void(0) if this is an issue.
In your case, the only way you can guarantee that you can close the tab/window is if you can guarantee that your form is being opened in a browsing context with no history or if you can open the form page via JavaScript. Whether or not those limitations are reasonable to work around depends on the specific structure/implementation of your website.
You can only close windows/tabs that you create yourself. That is, you
cannot programmatically close a window/tab that the user creates.
For example, if you create a window with window.open() you can close
it with window.close().
To make your code work, you should open up a window using JavaScript and then you'll will be able to close it by code.
You can use something like the below example code.
<script>
function openwindow() {
var pop = window.open("localhost","Ratting","width=550,height=170,0,status=0,")
var close = function() {
pop.close();
};
setTimeout(close, 2000);
}
</script>
<body>
<a href="javascript:void(0);" name="Window_Name" title="title_here" onClick="openwindow()" >Click here to open the child window</a>
</body>
you can use this concept on your ajax URL and ajax success stage.
$.ajax({
type: "POST",
url: function(){
var pop = window.open("localhost","Ratting","width=550,height=170,0,status=0,")
},
data: data,
success: function (resp) {
var close = function() {
pop.close();
};
setTimeout(close, 3000); // close after 3 seconds
},
error: //error code
}
});
HTML
<a class="closeButton">Close</a>
JavaScript
$('.closeButton').click(function () {
close();
});
You dont must use window.closed() or reopen tab and closed.
Just use this code.
For me its working.
I used to use the window.open(...).close() trick (which no longer works in Chrome or FireFox). In my case, there is a quit button in the (Java) application that, rather than trying to close the browser tab, cleans up, redirects back to the starting page and terminates. The user can then decide to:
manually close the tab
leave it open, or
re-enter the application
I realized that my real goal is not to close the browser tab, but to inform the user in an obvious way that the session is over.
In order to process special URLs in an already opened web application I use this approach:
the user receives a special URL in an email (alarm notifications)
the URL opens a small helper web page (H) with JavaScript code that temporarily sets a session cookie
the main web application (M), which is already open in another tab/window, recognizes this and handles the request after deleting the cookie
the helper web page (H) identifies this as a success and is now useless and should be closed.
This all works fine except for the helper window (H) remaining open.
Of course there is a small text saying "please close this window now" but it would be perfect if it could do this automatically.
window.close() causes a confirmation dialog in IE and FireFox just ignores the command. I understand this is because the window has not been opened using window.open().
Similarly, calling window.focus() in the main window does not do anything, either.
Does anyone have an idea how to accomplish this anyway? At least, automatically focusing the main window without closing the helper window would be better than nothing.
Of couse I'm also open for other solutions to handle e-mail links in an already open web application... :)
Note the web application (and the helper page of course) are on a HTTPS server.
In some browsers, a window can only be silently closed through javascript if it was opened via javascript (for security purposes).
This code is a hack to get around this security measure:
// open a new window, replacing the current one
window.open('', '_self', '');
// close the current window, which was now technically opened via javascript
window.close();
Use at your own risk. These measures are in place to prevent you from doing annoying/malicious things to visitors of your page.