chrome-extension:// links open about:blank - google-chrome

I've recently been contributing to the Enhanced Steam extension and I've found that a link fetched with chrome.extension.getURL simply opens about:blank and not the link described.
I do not believe it's actually a problem with the extension, but rather a problem in chrome. The link it supplies is valid (chrome-extension://pimjhgjngccknempdnehdeaihcjbajod/options.html) and navigating directly works correctly.
I tried chrome.tabs.create, but found that I am not allowed to use it due to the script modifying pre-existing content.
Any help or work arounds would be appreciated.

I put all my required files into "web_accessible_resources", it solved my problem. See this in #4 https://bugs.chromium.org/p/chromium/issues/detail?id=310870#c4
It is Chrome's previous problem which is not secure. In build 31.0.1650.57, Chrome fixed this which is to force to put required files in "web_accessible_resources". In Chrome extension, lots of samples don't use "web_accessible_resources", those are the bugs, those samples will have this "chrome-extension:// links open about:blank" problem in build 31.0.1650.57.
Actually my chrome extension MarkView was facing this issue and I had to update its manifest.json to make it work for this Chrome update. By the way, MarkView is tool to read and write Awesome Markdown Files, it provides features including Content Outline, Sortable Tables and code block syntax highlight with line number.

Looks like a bug in Chrome to me. If you don't have too many pages like this to change then could you try using message passing to pass the page you want to open to the background page? Then use either window.open or chrome.tabs.create within the background page. Example code shown below:
//CONTENT SCRIPT
chrome.runtime.sendMessage({greeting: "OpenPage", filename:"somepage.html", querystring:"?aValue="+someVal}, function(response) {});
Then in your Background page
//BACKGROUND PAGE
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.greeting == "OpenPage"){
open_page(request.filename, request.querystring)
}
});
function open_page(filename, querystring){
var pageUrl = chrome.extension.getURL(filename)+querystring;
chrome.tabs.create({'url': pageUrl }, function(tab) {
// Tab opened.
});
}

Related

Chrome sends two requests when downloading a PDF (and cancels one of them)

I noticed that whenever you download a PDF in Chrome, it consistently makes two requests, and then cancels one of them. This is causing the request to be registered twice in my Web app, which don't want. Is there a way to get Chrome to only make one request for PDFs?
I've researched this topic quite a bit now, and I have not found a sufficient answer. Closely-related answers suggest that the problem is that Chrome is looking for a favicon, but the network tab shows that it is actually making the same request twice, and then canceling the second request.
Is there a way to prevent Chrome from making the second request?
Below is a link to a random PDF file that I found through Google which when clicked should demonstrates the behavior. I would've posted a picture of my network tab in devtools but this is my first post on Stack Overflow, and the site is prohibiting me from uploading a picture.
https://www.adobe.com/enterprise/accessibility/pdfs/acro6_pg_ue.pdf
It looks like a bug in Chrome: https://bugs.chromium.org/p/chromium/issues/detail?id=587709
The problem is that Chrome, when it loads an iframe that returns a PDF stream, writes an "embed" tag inside that iframe which again contains the same URL as the iframe. This triggers a request for that URL again, but Chrome immediately cancels it. (see the network tab)
But by that time, the damage is done.
We have the same issue here, and it does not occur in Firefox or IE.
We're still looking for a good solution to this problem.
I'm still trying to find a proper solution but as a partial "fix" for now you could have two options
1) set the content disposition to "attachment" in the header
setting that to "inline" cause chrome to run a second cancelled call
so for example you can do something like that (nodejs resp in example)
res.writeHead(200, {
'Content-Type' : 'application/pdf',
'Access-Control-Allow-Origin' : '*',
'Content-Disposition' : 'attachment; filename=print.pdf'
});
unfortunately this solution will force the browser to download the pdf straight away instead of rendering it inline and that's not maybe desiderable
2) adding "expires" in the headers
this solution will always fire a second cancelled call but it's ignored by the server
so for example you can do something like that (nodejs resp in example)
res.writeHead(200, {
'Content-Type' : 'application/pdf',
'Access-Control-Allow-Origin' : '*',
'Content-Disposition' : 'inline; filename=print.pdf',
'Expires' : new Date(new Date().getTime() + (60000))
});
I had the same problem in an iframe. I turned of the PDF Viewer extension and the problem disappeared. I'm thinking the extension downloads the file twice. The first time to get the size, the second time to download with a progress bar (using the size gathered in the first request)
I've tried the other solutions and none worked for me, I'm a little late, I know, but just for the record, I solved this in the following manner:
Adding the download attribute:
In my case I was using a form, so it goes like this:
<form action="/package.zip" method="POST" download>
This worked on Brave and Safari, which previously showed the same problem, I think it will work for Chrome.
With my case, problem wasn't browser related. I've noticed our scrollbar plugin's (OverlayScrollbars) DOM manipulations reloads embedded pdf data and calls controller more than once due to on plugin's construct or destroy events. After I've initialized scrollbar before DOM is ready, problem is solved.

Controlling the "Oops! Chrome could not find ... " page?

When you type in an invalid address, Chrome displays a grey page that says "Oops! Google Chrome could not find X. Did you mean Y?"
Because this is not an HTTP page but rather one of the browser's built-in things, I can't put a content script in it and can't control it, so my extension is frozen until the user manually goes to another page.
Since the extension is supposed to be able to control the browser on its own, it's very important that anytime this page opens, it automatically goes back to a page I do have content script access to, and then displays a message instead.
Is this impossible?
You can use the chrome.webNavigation.onErrorOccurred to detect such errors, and redirect to a different page if you want. Unless you've got an extremely good reason to do so, I strongly recommend against implementing such a feature, because it might break the user's expectations of how the browser behaves.
Nevertheless, sample code:
chrome.webNavigation.onErrorOccurred(function(details) {
if (details.frameId === 0) {
// Main frame
chrome.tabs.update(details.tabId, {
url: chrome.runtime.getURL('error.html?error=' + encodeURIComponent(details.error))
});
}
});
According to the docs the only pages an extension can override are:
The bookmarks manager
The history
The new-tab
So, an extension can't change/contol/affect the behaviour of the browser regarding the "Oops!..." page.

Injecting DIV-Tag at top of page AND Automatic start of script when page is loading?

I started to program my own Chrome extension today and I'm stuck since hours with one problem.
Right now, I'm sending the current URL from the open website to my server where it's checked against some criterias and then a return value is sent back to the extension. This is working so far. I'm using only a popup.html, no background page.
The request is only sent when the user clicks on the icon in the browser.
How can I realize that the request is automatically sent, when the page is loaded?
If there is a specific return value from the server the user should be given an unannoying warning. Alert boxes and new windows are...well...annoying. Best way should be the little popup under the icon of the extension but that's not possible without a user's click. So I thought of a little -layer at the top of the page.
<html>
<head>
<script>
window.addEventListener("load", sendRequest, false);
function sendRequest() {
var q = "test";
xmlHttp=new XMLHttpRequest();
xmlHttp.open('GET', 'http://www.testurl.com/check.php?q='+q, true);
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4) {
document.getElementById("textf").innerText = xmlHttp.responseText;
chrome.tabs.executeScript(null,{code:"<div style='position: absolute; top: 0; left: 0; background-color=blue;layer-background-color: blue;'><p>test </p><p>test2 </p></div>"});
}
}
xmlHttp.send(null);
}
</script>
</head>
<body>
//Just for the popup...
<font color="blue"><p id="textf">Checking...</p></font>
</body>
</html>
If I do
chrome.tabs.executeScript(null,{code:"alert('testalert')"});
it gives me the alert. However, the isn't working and I can't figure out why :(
Do I need a background page for all this since I only want to check the URL when the page is loaded?
Why is the -thing not working but the alert is?
Thank you in advance!
chrome.tabs.executeScript is for JavaScript only. To add content to a Web page, you must write JavaScript that manipulates the DOM. A good place for you to start learning this may be Mozilla's DOM docs. (DOM is a W3C standard and Chrome has implemented it, so yes, Mozilla pages are relevant here.)
If I may say so, it sounds like the best way forward for you is to scrap this and start over with a content script defined in your manifest so that Chrome will execute it for you; check the Content Scripts documentation to learn more. Since you're trying to accomplish your goal with no background page, and would therefore need to use XMLHttpRequest directly from your content script, you should add "minimum_chrome_version": "13" to your manifest, as Chrome 12 and earlier won't let you do that.
By the way, practically no one will understand what you're talking about when you use "-layer" and "-thing" like that. Please be more careful in making sure you are using proper terminology. Ask your peers if you're unsure of the proper term for something.

HTML5 History API with Standard links

So, after redesigning my site, I thought I would use the HTML5 history API, when I saw brilliant use of it here: http://diveintohtml5.ep.io/examples/history/casey.html
Problem is, the code provided doesn't work for me, (using Chrome 8).
Not entirely sure why, but it simply refreshes the page with the href value of the link after the partial content is successfully loaded.
Are there any other examples of this use of the API? I dont want History.js or anything like that as that uses hash/hashbangs as a fallback. I'm trying to get rid of these.
Any ideas?
edit: Firebug throws a 'link has no value' at me as well as countless requests for the partially loaded content. After these the page refreshes
You have to intercept the link click and call your own pushState - if you check out the code on the page you will see the event handler:
function addClicker(link) {
link.addEventListener("click", function(e) {
if (swapPhoto(link.href)) {
history.pushState(null, null, link.href);
e.preventDefault();
}
}, true);
}

Could I make a Google Chrome extension for chrome pages (downloads, extensions etc)?

I'd like to make a very simple extensions that slightly alters how the Downloads page looks. Changing the History page might be interesting too, but that's for later.
Is there a way to do that?
I tried making a Content Script extension, with "chrome://downloads" as match in manifest.json. Chrome won't allow that and responds with an error when packaging the extension.
Is there another simple way? It has to be simple, because changes would be simple, because all chrome:// pages are built with HTML, JS and CSS.
edit
After trying with background scripts a little...
I can't get chrome.tabs.executeScript to work! I added in background.html:
chrome.browserAction.onClicked.addListener(function(tab) {
alert(this.document.body.innerHTML);
alert(chrome.tabs.executeScript(null, {
code : "document.body.style.backgroundColor = 'red';"
}));
});
And I added this in manifest.json to add a (invisible) 'browser action button':
,"browser_action": {
/* "popup": "background.html",*/
"name": "Alter page"
}
The onClicked event fires both alerts (first is background.html's body, second is undefined). But the code (a string with document.body.style.backgroundColor = 'red';) doesn't execute! And ofcourse there's no debugging for extensions like this =)
Any tips anyone? I'm trying to get a hold of the tab's window.document (not background.html's window.document!). An injected script (that's what chrome.tabs.executeScript is supposed to do) should do that.
PS
I'm stealing from make_page_red/manifest and make_page_red/background.html
The 'extension' I have so far: http://hotblocks.nl/js/downloads.rar
EDIT
I found out what I want to achieve is possible with just CSS. I don't need to inject javascript. Does that make it easier? Does that make it possible? =)
According to this documentation, chrome:// URLs are an invalid scheme so they won't be matched:
A match pattern is essentially a URL that begins with a permitted scheme (http, https, file, or ftp), and that can contain '*' characters.
I would look into using override pages instead.
As requested, here's my extension that can at least load when chrome://downloads is loaded, although as I said, I don't think you can modify the page even if you know that's the page you're viewing.
manifest.json
{
"name": "Test",
"version": "0.0.1",
"background_page": "background.html",
"permissions": [
"tabs"
]
}
background.html
<script>
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab)
{
if (tab.status == "complete")
{
alert(tab.url);
// should alert 'chrome://downloads' on that page. You can
// check for this url here and then do whatever you want
}
});
</script>
Update: Since Chrome 31 there is an API for extensions that allows access to Chrome's downloads: https://developer.chrome.com/extensions/downloads
There's also an API that allows access to list and manage other installed extensions: https://developer.chrome.com/extensions/management
(Previous Answer)
Unfortunately, there's not currently an API for Chrome extensions to access information about a user's downloads. It's a widely requested feature, though, and there's some discussion among Chrome developers here: http://code.google.com/p/chromium/issues/detail?id=12133
Star the issue if it's a feature that you'd like to see, and you'll receive email updates.
As this page shows, there is no API to override the downloads page... However, there is a way to make a file you have made replace the chrome://downloads/ page whenever it is loaded using javascript in your background page...
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab){
if(changeInfo.status === "loading"){
if(tab.url === "chrome://downloads/"){
chrome.tabs.update(tab.id, {url: "REPLACEMENT.html"});
}
}
});
Essentially what this does is - As soon as the page chrome://downloads begins loading (using the tabs.onUpdated API), the page is redirected to REPLACEMENT.html (Using tabs.update API)... There is no visible delay in the tab update
as this script is run before the chrome://downloads page begins loading... You can use a similar code in your file by pressing CTRL + U on the downloads page to view and copy its source code