Opening custom protocol URL doesn't work consistently in Chrome - google-chrome

The following code supposes to open a URL in an external app:
var a = document.createElement('a');
a.href = 'myprotocol:jdoe#example.com;fromuser=John%20Doe;mode=audiovideo';
document.body.appendChild(a);
a.click();
When the app is not installed, on some PCs Chrome fails silently while on the others it displays this window:
Where is this behavior defined?

Application association to URI Schema
If you want to register your app to handle a specific URI Schema in Windows, then you should register it in registry. It is explained in MSDN article and Googling "Registering an Application to a URI Scheme" gives plenty of examples.
HKEY_CLASSES_ROOT/
your-protocol-name/
(Default) "URL:your-protocol-name Protocol"
URL Protocol ""
shell/
open/
command/
(Default) PathToExecutable
Web App schema registration
You can register a custom protocol handler with Google Chrome using navigator.registerProtocolHandler (Firefox has the feature too).
navigator.registerProtocolHandler(
'web+mystuff', 'http://example.com/rph?q=%s', 'My App');
Please note, that your protocol has to start with web+. Otherwise you would get SECURITY_ERR: DOM Exception 18 error.
Or, if you are developing a Chrome App, then you can register your handlers in your manifest file.
"url_handlers": {
"view_foo_presentation": {
"matches": [
"https://www.foo.com/presentation/view/*"
],
"title": "View Foo presentation"
}
}
You can also look into the Chrome URLs (chrome://chrome-urls/) and see if you can change it in any of the settings.

Related

How to make a Chrome Extension to redirect when specific pages are accessed in Manifest V3

I'm trying to make a Chrome extension that redirects to a pre defined page when a specified page is loaded.
I'm using webRequest for this, But now that I have to migrate to Manifest V3, webRequest can not be used anymore.
Can anyone help me with rewrite the script to make it work with Manifest V3?
Here's the script that I use to redirect pages:
var host = "http://example.com";
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
return {redirectUrl: host + details.url.match(/^https?:\/\/[^\/]+([\S\s]*)/)[1]};
},
{
urls: [
"*://foo.com/demo*",
"*://www.foo.com/test/*"
],
types: ["main_frame", "sub_frame", "stylesheet", "script", "image", "object", "xmlhttprequest", "other"]
},
["blocking"]
);
I would not recommend using declarativeNetRequest for this task, it is very limited in its capabilities and has an awkward interface.
It sounds like you want to redirect the user prior to the page being loaded. If that's the case, you need to hook into the request/response lifecycle using chrome.debugger API. I describe how to do that here- his application seems easily adaptable to your own. This is the only way to get the same caliber request manipulation capabilities in MV3 as in MV2.
Alternative approach:
-Use the chrome.webNavigation API. This will just entail setting up event listeners/handlers for one or more of the following:
onBeforeNavigate -> onCommitted -> [onDOMContentLoaded] -> onCompleted
Here you can find many examples of other projects using this API.

WebApp: Failures: Service worker does not successfully serve the manifest's start_url

After testing the web app with Lighthouse I have such error:
User will not be prompted to Install the Web App Browsers can
proactively prompt users to add your app to their homescreen, which
can lead to higher engagement. Learn more.
Failures: Service worker
does not successfully serve the manifest's start_url.
All the criteria described here are satisfied:
The site is served over HTTPS.
A service worker is registered.
The scope of the service worker includes the page you audited and the page specified in the start_url property of the web app manifest.
A web app manifest exists and meets the following criteria: Has a
valid name property. Has a valid short_name property. Has a valid start_url property. Has a valid display property and the value is
standalone, fullscreen, or minimal-ui. Specifies an icon that is at
least 192px by 192px.
The manifest files is rendered via script. Important variables are
scope_url = 'https://website.com/app/'
start_url = 'https://website.com/app/about/'
ServiceWoker.js is quite simple:
self.addEventListener('push', function(e) {
...
});
self.addEventListener('notificationclick', function (e) {
...
);
Web App and sw.js are served from start_url.
What else can I check?
Edit 1. When I try to "Add to homescreen" from Chrome console I get:
Site cannot be installed: the page does not work offline
what is close to this comment
After changing start_url to 'https://website.com/app/'
and adding:
self.addEventListener('fetch', function(e){
});
to serviceWorker.js the problem has been solved.
It seems that a recent version of chrome-devtools-lighthouse verifies that the your start_url is served successfully (some content and response code 200 is returned) even while the device is offline.

Chrome Packaged App written with DART : how to enable Webview tag to download files

I have this Chrome Packaged App written in DART, and I want to allow tag to show the PDF comes as an attachment (Content-disposition:attachment; ) with HTTP response from an external link.Similar to the issue described here : Chrome packaged application - downloading file from Webview , but my app is in DART so there are some limitations. I am getting Permission error : ": The permission request for "download" has been denied." , I see a lot of examples on how to enable this from JS, but is there a way to do it with the Chrome API on DART ? or is there any other workaround to just display the PDF ?
You can try dart-js-interop
var webview = document.querySelector('#app-webview');
webview.on['permissionrequest'].listen((e) {
var evt = new js.JsObject.fromBrowserObject(e);
if (evt['permission'] == 'download') {
evt['request'].callMethod('allow', []);
}
});

Cannot run xmlhttprequest in Chrome App : provisional headers & No 'Access-Control-Allow-Origin'

I am building a chrome app sending a Get HTTPRequest to an external API:
I get the answer:
XMLHttpRequest cannot load
http://developer.echonest.com/api/v4/artist/profile?api_key=FILDTEOIK2HBORODV&name=weezer.
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'chrome-extension://ihdfphmemcdeadpnjkhpihmcoeiklphe'
is therefore not allowed access.
I did allow the external domain in permissions in my manifest (to prevent blocking in cross domain requests)
When I type the URL in the Address Bar it works perfectly
It seems Chrome is blocking my request, I even tried to load directly the script in an HTML page and it does not work (same message but with origin "null") (oh and it did not allow me to cheat by changing the Origin in the Header).
I also get the famous "Caution : Provisional Headers are shown" in the console, which makes me think Chrome is blocking my request, I looked up on other Stack Overflow Questions but apart running chrome://net-internals and looking for stuff I haven't the first clue about I cannot find any good answers (I did run chrome://net-internals but really can't make any sense out of it).
Here is the request :
function update_stations() {
var xhr = new XMLHttpRequest();
xhr.open("Get","http://developer.echonest.com/api/v4/artist/profile?api_key=FILDTEOIK2HBORODV&name=weezer", true);
xhr.responseType = "json";
xhr.onreadystatechange = function() {
console.log("Essai");
console.log(xhr.readyState);
console.log(xhr);
document.getElementById("resp").innerText = xhr;
}
xhr.send()
}
Any thoughts (would be highly appreciated)?
Cross-Origin XMLHttpRequest chrome developer documentation explains that the host must be listed in the permissions of the manifest file.
I've taken the XHR code from above and included it in the hello world sample. It works after adding the following to the manifest.json.
"permissions": [
"http://*.echonest.com/"
]

Can local storage databases be cross-accessed between separate Chrome extensions?

Question I think is self explanatory, but if you need more, here it is:
Chrome Extension A saves an email address in localstorage.
Chrome Extension B wants to see that email address.
Is this permitted? (This might be more of an HTML5 thing than a Chrome-specific thing, but my knowledge is limited so I'll frame it within the context of my desire to know the answer).
If you own the two extensions, for instance, your the one maintaining both extensions. You can definitely use cross extension message communication to pass that email or even localStorage to the other extension.
For example, take a look at my extension here:
https://github.com/mohamedmansour/reload-all-tabs-extension/tree/v2
One extension is the core, and the other one is just the browser action (right now they are merged as of v3) but v2 lets them both communicate to each other. The browser action sends a "ping" event, and the core extension listens on such event and returns a "pong". The browser action extension is an "Add-On" to the core extension. When you open up "Options", it uses the options from the core one.
Back to your questions ... To access localStorage cross extensions, you can do something like this:
main core extension:
localStorage['foo'] = 'bar';
var secondary_extension_id = 'pecaecnbopekjflcoeeiogjaogdjdpoe';
chrome.extension.onRequestExternal.addListener(
function(request, sender, response) {
// Verify the request is coming from the Add-On.
if (sender.id != secondary_extension_id)
return;
// Handle the request.
if (request.getLocalStorage) {
response({result: localStorage});
} else {
response({}); // Snub them.
}
}
);
secondary extension:
var main_extension_id = 'gighmmpiobklfepjocnamgkkbiglidom'
chrome.extension.sendRequest(main_extension_id, {getLocalStorage: 1},
function (response) {
var storage = response.result;
alert(storage['foo']); // This should print out 'bar'.
}
);
BTW, I really didn't test this extension. I just copied and pasted from the reload all tabs extension that did something similar.
Not directly, but you can send messages between extensions. So if an extension that stores emails is expecting a request from some external extension, it could read the required data and send it back. More about it here.