问题
I am trying to detect if my application to handle a custom protocol is installed and working using the different browsers. I have looked at other questions on this site such as: How to detect browser's protocol handlers?, and have looked at resources like this to make it work on most platforms in most browsers.
Before you flag this as duplicate, hear me out...
I was able to get my function working on everything except Chrome on Windows 8+. I cannot use the window focus method on Chrome like I can on Windows 7 because it pops up the message that asks me to find an app in the store.
Is there any way (short of an extension) to detect a custom protocol handler in Windows 8+ on Chrome?
UPDATE:
Using an onBlur to detect it only works on Windows 7, because in 8+, if it doesn't find something to open your protocol, it opens the 'find something from the app store' dialog that makes the browser lose focus.
回答1:
Hey I think you were on the right track. It is definitly not that easy but chrome so far was not my problem, more like Edge + IE but my solution is assuming they don't support the protocol if anything fails or they don't respond correctly which they do sometimes.
The blur/focus is something to check but you need to check it in combination with a visibility change. The HTML5 Visiblity API and this post about it helped me figure out a solution that is pretty solid except the mentioned browsers above because they have some issues with the navigator.msLaunchUri function and have their own approach implemented which doesn't rely on blur/focus. But the function is bugged and doesn't respond correctly all the time.
You can find my codepen here. Hopefully that helps you even though it is a bit late for an answer. This works for mobile browsers as well but I didn't test multiple yet worked for my Android 6.0.2. Might need some tweaks in the long run but I think it is pretty solid.
(function() {
var noProtocolHash = '#protocolXYnotsupported',
checkDelay = 800, // apps might start slowly
isBlurred = false,
inCheck = false,
inLauncherCheck = false,
tabVisible = (function(){
var stateKey,
eventKey,
keys = {
hidden: "visibilitychange",
webkitHidden: "webkitvisibilitychange",
mozHidden: "mozvisibilitychange",
msHidden: "msvisibilitychange"
};
for (stateKey in keys) {
if (stateKey in document) {
eventKey = keys[stateKey];
break;
}
}
return function(c) {
if (c) document.addEventListener(eventKey, c);
return !document[stateKey];
}
})(),
isMSIE = function(){
var rv = -1;
if(navigator.appName == 'Microsoft Internet Explorer'){
var ua = navigator.userAgent;
var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
if(re.exec(ua) != null){
rv = parseFloat(RegExp.$1);
}
}
else if(navigator.appName == 'Netscape'){
var ua = navigator.userAgent;
var re = new RegExp("Trident/.*rv:([0-9]{1,}[\.0-9]{0,})");
if(re.exec(ua) != null){
rv = parseFloat(RegExp.$1);
}
}
return (rv !== -1)? true: false;
},
isEdge = function(){
return window.navigator.userAgent.indexOf("Edge") > -1;
},
checkIfFocusLost = function($el){
try {
document.location.href = $el.attr("href");
} catch (ex) {
document.location.href = document.location.href + '/' + noProtocolHash;
}
setTimeout(checkVisibility, checkDelay);
},
checkVisibility = function(){
if(tabVisible() && !isBlurred){
handleNoProtocol();
}
else {
handleProtocol();
}
},
handleNoProtocol = function(){
$('.result').text('has no protocol');
inLauncherCheck = false;
},
handleProtocol = function(){
$('.result').text('has the protocol');
inLauncherCheck = false;
},
checkHash = function(){
if(document.location.hash === noProtocolHash){
handleNoProtocol();
}
},
checkLauncherProtocol = function($el){
inLauncherCheck = true;
navigator.msLaunchUri($el.attr("href"), function(){
handleProtocol();
},
function(){
handleNoProtocol();
});
setTimeout(function(){
// fallback when edge is not responding correctly
if(inLauncherCheck === true){
handleNoProtocol();
}
}, 500);
},
checkIfHasProtocol = function($el){
inCheck = true;
if(isEdge() || isMSIE()){
checkLauncherProtocol($el);
}
else {
checkIfFocusLost($el)
}
};
checkHash();
tabVisible(function(){
if(tabVisible() && inCheck){
handleProtocol();
inCheck = false;
}
});
window.addEventListener("blur", function(){
isBlurred = true;
});
window.addEventListener("focus", function(){
isBlurred = false;
inCheck = false;
});
window.checkIfHasProtocol = checkIfHasProtocol;
})();
$('.protocol').click(function(e) {
checkIfHasProtocol($(this));
e.preventDefault();
});
My code is tested with Win10: Chrome, Firefox, IE11, Edge + Android: Chrome (6.0.1)
there is also this github project https://github.com/ismailhabib/custom-protocol-detection which sorta has a similar approach maybe a little bit more maintained but i couldn't get their solution working for some reasons but maybe this is exactly what you need.
回答2:
I think this might help you here with different browsers, but please define you question better or add at least some kinda example to make it clear.
来源:https://stackoverflow.com/questions/29108347/detecting-custom-protocol-handler-in-windows-8-with-chrome