Why don't the
window.addEventListener('afterprint', (event) => {
console.log('After print');
});
window.onafterprint = (event) => {
console.log('After print');
};
commands work on PDF pages? I made a code to send a message to my background.js after print, the code works perfectly on all chrome pages, but on PDF pages they just don't work, and they don't return any kind of error?
"permissions": ["tabs",
"activeTab",
"nativeMessaging",
"scripting"],
"host_permissions": [
"http://*/*",
"https://*/*"
],
"content_scripts":[
{
"js": ["popup.js"],
"matches": ["<all_urls>"]
}
PDf viewers like Acrobat for browsers or modern replacements like Chromium's (Brave Edge etc.) using inbuilt Foxit Skia extension, are Integrated Standalone Binaries.
Here we can see an alternate one, both files are web url entries, but the principle is EXACTLY the same it is either standalone, plugged-in or integrated.
Left is Windows Trident inbuilt System - - - - - - - Right is Mozilla web browser
What you can note in this case is there is NO pdf print just save as PDF. It is not the fact that there's no print function in this example, to respond it is the fact ALL are secured against outside tampering, as they are running in the clients system.
No feedback at all, once a PDF is in a PDF editor/viewer, rather than the HTML editor we call a browser.
Related
I have a Chrome extension that can (if you allow access to file URLs) grab your local pdf file that you have open in chrome and send it on to our API for processing. This is done by fetching the pdf with XMLHttpRequest to file:///Users/user/whatever/testfile.pdf from the background script.
When migrating to manifest v3 for a Chrome extension the background script becomes a service worker. In a service worker only fetch is available, not XMLHttpRequest. Problem is, fetch only supports http and https, not file:// urls. So how can I make the same feature of having the Chrome extension fetching/getting the local file?
EDIT: Things I also tried:
Making the XMLHttpRequest from injected iframe as suggested by answer.
This gives error net:ERR_UNKNOWN_URL_SCHEME when making the request
Making the XMLHttpRequest from injected content script.
This gives error Access to XMLHttpRequest at 'file:///.../testfile1.docx.pdf' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, chrome-untrusted, https.
From what I can understand from a lot of research access to file:// is in general blocked and Chrome extension background scripts used to be an exception to this. Seems to me it was never allowed from content scripts or action popups.
My manifest.json for reference:
{
"manifest_version": 3,
"name": "..",
"version": "0.1",
"icons": {
"16": "assets/icon-16x16.png",
"48": "assets/icon-48x48.png",
"128": "assets/icon-128x128.png"
},
"action": {
"default_title": ".."
},
"background": {
"service_worker": "background.js"
},
"permissions": [
"webRequest",
"activeTab",
"scripting",
"storage",
"unlimitedStorage",
"identity",
"pageCapture"
],
"host_permissions": [
"<all_urls>"
],
"web_accessible_resources": [{
"resources": ["iframe.html"],
"matches": [],
"extension_ids": []
}]
}
The content script is injected programmatically (using webextension-polyfill for promise support)
browser.action.onClicked.addListener(async (tab: Tab) => {
await browser.scripting.executeScript({files: [ "inject.js" ], target: {tabId: tab.id}});
});
Chrome 98 and older can't do it in the background service worker for the reasons you mentioned.
There was also a bug that prevented doing it in a normal visible chrome-extension:// page or iframe. It's fixed in Chrome 91.
Solution
Use fetch in Chrome 99 and newer.
In older versions use the following workarounds.
Workaround 1: File System API, Chrome 86+
A ManifestV3 extension can use the new File System API to read the contents of the file, for example inside the iframe exposed via web_accessible_resources.
Workaround 2. Extension frame, Chrome 91+
Use a content script that runs in the tab with that pdf:
matches in manifest.json should contain <all_urls> or file://*/* and file access should be enabled by the user in
chrome://extensions UI for your extension. Alternatively you can use
activeTab permission and programmatic injection when the user
clicks your extension's icon or invokes it through the context menu.
The content script adds an invisible iframe that points to iframe.html file exposed in web_accessible_resources
The iframe.html loads iframe.js which uses XMLHttpRequest as usual. Since the iframe has chrome-extension:// URL its environment
is the same as your old background script so you can do everything
you did before right there.
Workaround 3. Extension window/tab, Chrome 91+
An alternative solution is to use any other visible page of your
extension like the action popup or options page or any other
chrome-extension:// page belonging to your extension as they can
access the file:// URL via XMLHttpRequest same as before.
Notes
File access should be enabled in chrome://extensions page for this extension.
I create a chrome extension which offer accessibility to download any media in opened page of Facebook, including photo, video, and story. But I'm stuck when about to access/catch facebook's video story request URL that's shown up in Network tab in console, using chrome.webRequest API.
By excluding bytestart and byteend params from URL above, we got the full video file (with an expiration token). The <video> tag itself has src attribute like blob:https://www.facebook.com/<some_alpha_numerics_and_hyphens>.
This is what I've tried in my extension project:
permission:
"permissions": [
"webRequest",
"*://*/*"
],
I've tried to listen all the events available but no luck.
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
console.log('onBeforeRequest', details.url);
},
{
urls: ["<all_urls>"]
}
);
// onBeforeSendHeaders
// onSendHeaders
// onHeadersReceived
// onAuthRequired
// onResponseStarted
// onBeforeRedirect
// onCompleted
// onErrorOccurred
I haven't tried chrome.declarativeWebRequest https://developer.chrome.com/extensions/declarativeWebRequest because it's for Beta and Dev channels only.
Is it really possible or did I have mistake in using it? Thank you in advance.
I would recommend adding the "webRequestBlocking" permission to your manifest.json file.
According to the documentation the callback uses a blocking event handler that requires the "webRequest" as well as the "webRequestBlocking" permission in order to work.
Reference: https://developer.chrome.com/extensions/webRequest#examples
I'm writing a chrome extension, to do some modification to the page content, but I have to click on it to make it working on current page.
What I want is: if I click on the extension icon (to enable it), it will always enabled, no matter what new pages/tabs are open, and will work on them?
How to write code to configure it?
Using content script you can achieve this. Content scripts are files that run in the context of web pages so you can modify webpage content.
Add below code in manifest.json
{
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],
"js": ["your-content-script.js"]
}
],
"permissions": [
"tabs", "http://*/*","https://*/*"
]
}
To learn more, read this https://developer.chrome.com/extensions/overview.html#arch
In my extension I use chrome.webRequest to catch requests from any web pages and it works like a charm.
But I can not catch any requests initialized from another extension.
My manifest:
"permissions": [
"tabs",
"webRequest",
"webRequestBlocking",
"<all_urls>"
],
background.js:
chrome.webRequest.onBeforeRequest.addListener(function (data) {
console.log('catched', data);
}, {urls: ['<all_urls>']});
Tests:
open tab with http://google.com:
catched https://www.google.com/
open extension console and run fetch('http://google.com'):
catched http://google.com/
open another extension console and run fetch('http://google.com'):
// no output
Does anybody know if is it possible and if so, how to set it up?
Thanks!
Updated
My previous answer it not correct, see #Rob W's comments.
But when #Xan mentioned that extension URLs were visible to other extensions, it became apparent that this behavior is undesirable and a security issue, so I removed the ability for extensions to see other extensions' requests
Previous answer
It's not allowed to handle requests sent from other extensions.
In addition, even certain requests with URLs using one of the above schemes are hidden, e.g., chrome-extension://other_extension_id where other_extension_id is not the ID of the extension to handle the request, https://www.google.com/chrome, and others (this list is not complete).
I had a good idea, which kind of revolves around ips from the server the user is on.
Im very new to making a google chrome extension, but i am good at the programming languages that requires to build one .
Question: Can I get a IP from a server that the user is on? and if so how would you do this?
I was thinking just AJAX the url to my own server which then pings the server which would get the ip and returns that/stores it some where.
You can get current URL of tab\web Pageuser is currently browsing using chrome.tabs API
Demonstration
chrome.tabs.query({
"currentWindow": true, //Filters tabs in current window
"status": "complete", //The Page is completely loaded
"active": true // The tab or web page is browsed at this state,
"windowType": "normal" // Filters normal web pages, eliminates g-talk notifications etc
}, function (tabs) { //It returns an array
for (tab in tabs) {
_url_i_need = tabs[tab].url;
//Do AJAX Stuff here
}
});
Ensure you declare tabs permission in your manifest as shown here
{
"name": "My extension",
...
"permissions": [
"tabs"
],
...
}
References
Tabs API