브라우저의 프로토콜 핸들러를 감지하는 방법은 무엇입니까?


82

사용자 지정 URL 프로토콜 처리기를 만들었습니다.

http://

mailto://

custom://

이에 따라 대응할 수 있도록 WinForms 애플리케이션을 등록했습니다. 이것은 모두 훌륭하게 작동합니다.

그러나 사용자가 아직 사용자 지정 URL 프로토콜 처리기를 설치하지 않은 경우를 정상적으로 처리 할 수 ​​있기를 바랍니다.

이 작업을 수행하려면 브라우저에 등록 된 프로토콜 처리기를 감지 할 수 있어야합니다. JavaScript에서 가정합니다. 하지만 정보를 조사 할 방법을 찾지 못했습니다. 이 문제에 대한 해결책을 찾고 싶습니다.

공유 할 수있는 아이디어에 감사드립니다.


5
크롬 (예 : XPCOM, ActiveX 등) 코드에서만 가능하다고 생각합니다. 그렇지 않으면 개인 정보 보호 문제가됩니다 ( "Eudora를 사용하는 것으로 감지되었습니다. 오늘 FooMail로 전환하십시오!"). 하지만 관심있는 브라우저 / OS가 무엇인지 명시 해주세요.
Matthew Flaschen

1
좋은 지적입니다.하지만 제가 소유 한 프로토콜 acsfs : // Windows IE, FireFox 및 이상적으로 Safari를 처리하기 위해 등록 된 것이 있다는 사실을 알게되어 기쁩니다
Chris Craft

이 문제를 이미 해결 했습니까?
jstuardo

답변:


35

이것은 이것을하기위한 매우 , 매우 해키 한 방법 일 것입니다. 그러나 이것이 작동할까요?

  • 링크를 정상적으로 넣으십시오 ...
  • 그러나 타이머를 설정하고 창에 대한 onblur 핸들러를 추가하는 onclick 핸들러를 첨부하십시오.
  • (이론상) 브라우저가 링크 (응용 프로그램 X)를 처리하면 창에서 포커스를 훔치면서로드됩니다.
  • onblur 이벤트가 발생하면 타이머를 지우십시오 ...
  • 그렇지 않으면 3-5 초 후에 시간 초과가 발생하도록하고 사용자에게 "음, Mega Uber Cool 애플리케이션이 설치되지 않은 것 같습니다 ... 지금 설치 하시겠습니까? (OK) (취소)"라고 알립니다.

방탄과는 거리가 멀지 만 도움이 될까요?


1
: D 영리한 아이디어입니다. 공통된 필요처럼 보이기 때문에 길이있을 것 같습니다.
Chris Craft

2
Mac의 Firefox (아마도 더 많은 브라우저)에서 사용자 지정 프로토콜을 사용하는 응용 프로그램이 실행되지 않더라도 창이 포커스를 잃고 onblur가 실행됩니다.
quano

이것은 프로토콜에 대한 오류 처리가 없기 때문에 Chrome에 적합한 솔루션입니다. 이것은 여기에 다른 브라우저의 감지와 함께 사용되었습니다 rajeshsegu.com/2012/09/browser-detect-custom-protocols/...
자극 페이튼

프로토콜 탐지는 최근에 큰 골칫거리였습니다. ;) 위의 방법은 다소 작동하는 것 같습니다. rajeshsegu.com/fun/code/browser/detect.html에 있는 rajesh의 라이브 예제를 사용하면 Chrome에 "진실"이 적용됩니다. 그러나 결과 () 함수가 없도록 리팩터링하고 (경고 상자-차단 호출을 사용함) 부울을 반환하도록하면 거짓이됩니다. 나는 차단 경고가 어떻게 든 타이밍을 강제하는 해키 방법이라는 것을 어떻게 든 느낍니다 ... 어떤 통찰력, @scunliffe?
Greg Pettit 2014

이 방법은 사용자가 Win8을 사용하여 답변을 기억하도록 선택하고 응용 프로그램이없는 경우를 제외하고 Chrome에서 작동합니다. 이 경우에 흐림 이벤트는 응용 프로그램이 실행되지 수 있지만 일
폴 Haggo

18

이를 수행하는 훌륭한 크로스 브라우저 방법은 없습니다. Win8 +의 IE10 +에서 새 msLaunchUriAPI를 사용하면 다음과 같이 프로토콜을 시작할 수 있습니다.

navigator.msLaunchUri('skype:123456', 
  function() 
  { 
    alert('success');
  }, 
  function()
  {
    alert('failed');
  } 
); 

프로토콜이 설치되지 않은 경우 실패 콜백이 실행됩니다. 그렇지 않으면 프로토콜이 시작되고 성공 콜백이 실행됩니다.

이 주제에 대해서는 여기에서 조금 더 논의합니다. http://blogs.msdn.com/b/ieinternals/archive/2011/07/14/url-protocols-application-protocols-and-asynchronous-pluggable-protocols-oh-my .aspx


IT는 NOT 작업을 수행 - 윈도우 7에서 테스트, IE 브라우저

6
msLaunchUri는 Windows 8 이상 전용입니다.
EricLaw

링크가 끊어졌습니다.
Qiulang

16

HTML5는 사용자 정의 스키마와 콘텐츠 핸들러를 정의합니다 (내가 아는 한 Firefox가 유일한 구현 자임). 불행히도 현재 핸들러가 이미 존재하는지 확인할 방법 이 없습니다. 제안 되었지만 후속 조치는 없었습니다. 이것은 사용자 정의 핸들러를 효과적으로 사용하기위한 중요한 기능으로 보이며 우리는 개발자로서이 문제를 구현하기 위해주의를 기울여야합니다.


13

프로토콜 핸들러를 등록한 설치된 앱의 존재를 감지하는 자바 스크립트를 통한 직접적인 방법은없는 것 같습니다.

iTunes 모델에서 Apple은 서버에 URL을 제공 한 다음 일부 자바 스크립트를 실행하는 페이지를 제공합니다.

http://ax.itunes.apple.com/detection/itmsCheck.js

따라서 iTunes 설치 프로그램은 분명히 존재를 감지 할 수있는 주요 브라우저 용 플러그인을 배포합니다.

플러그인이 설치되어 있으면 앱별 URL로 리디렉션이 성공할 것이라고 합리적으로 확신 할 수 있습니다.


2
이것이 가장 신뢰할 수있는 솔루션이어야합니다. 그러나 나는 대부분의 브라우저에 대한 플러그인을 설치하고 만들어야한다는 것을 의미합니다. 대신 사용자를 다운로드 페이지로 리디렉션 할 수 있도록 더 사용자 친화적 일 수 있습니다.
NATIM

여기에 언급 된대로 FireBreath를 사용하지 않는 이유는 무엇입니까? stackoverflow.com/a/14758085/427793
swdev 2014

10

가장 쉬운 해결책은 사용자에게 처음으로 묻는 것입니다.

예제에 따라 자바 스크립트 확인 대화 상자 사용 :

You need this software to be able to read this link. Did you install it ?

if yes: create a cookie to not ask next time; return false and the link applies
if false: window.location.href = '/downloadpage/'

쿠키는 매일 깨끗하게 제거 할 수 있습니다. 플래시 기반 쿠키를 만들 수있는 더 좋은 방법이 없습니까?

쿠키가 제거되면 사용자에게 다시 메시지가 표시됩니다.
Natim 2014 년

5

실행하려는 프로그램 (코드)을 제어 할 수있는 경우 사용자가 응용 프로그램을 성공적으로 실행했는지 확인하는 한 가지 방법은 다음과 같습니다.

  1. 사용자 정의 프로토콜을 열기 전에 사용자의 의도를 데이터베이스에 저장하는 서버 스크립트에 AJAX 요청을 작성하십시오 (예 : 사용자 ID 및 원하는 작업 저장).

  2. 프로그램을 열고 의도 데이터를 전달하십시오.

  3. 프로그램이 데이터베이스 항목을 제거하도록 서버에 요청하도록합니다 (정확한 행을 찾기 위해 의도 데이터 사용).

  4. 데이터베이스 항목이 사라 졌는지 확인하기 위해 잠시 동안 자바 스크립트가 서버를 폴링하도록합니다. 항목이 없어지면 사용자가 응용 프로그램을 성공적으로 열었 음을 알 수 있습니다. 그렇지 않으면 항목이 유지됩니다 (나중에 cronjob을 사용하여 제거 할 수 있음).

나는이 방법을 시도하지 않고 단지 생각했다.


4

마침내 이것 과 매우 간단한 Safari 확장 프로그램 의 조합으로 작동하는 크로스 브라우저 (Chrome 32, Firefox 27, IE 11, Safari 6) 솔루션을 얻을 수있었습니다 . 이 솔루션의 많은 부분이이 질문다른 질문 에서 어떤 식 으로든 언급되었습니다 .

다음은 스크립트입니다.

function launchCustomProtocol(elem, url, callback) {
    var iframe, myWindow, success = false;

    if (Browser.name === "Internet Explorer") {
        myWindow = window.open('', '', 'width=0,height=0');
        myWindow.document.write("<iframe src='" + url + "'></iframe>");

        setTimeout(function () {
            try {
                myWindow.location.href;
                success = true;
            } catch (ex) {
                console.log(ex);
            }

            if (success) {
                myWindow.setTimeout('window.close()', 100);
            } else {
                myWindow.close();
            }

            callback(success);
        }, 100);
    } else if (Browser.name === "Firefox") {
        try {
            iframe = $("<iframe />");
            iframe.css({"display": "none"});
            iframe.appendTo("body");
            iframe[0].contentWindow.location.href = url;

            success = true;
        } catch (ex) {
            success = false;
        }

        iframe.remove();

        callback(success);
    } else if (Browser.name === "Chrome") {
        elem.css({"outline": 0});
        elem.attr("tabindex", "1");
        elem.focus();

        elem.blur(function () {
            success = true;
            callback(true);  // true
        });

        location.href = url;

        setTimeout(function () {
            elem.off('blur');
            elem.removeAttr("tabindex");

            if (!success) {
                callback(false);  // false
            }
        }, 1000);
    } else if (Browser.name === "Safari") {
        if (myappinstalledflag) {
            location.href = url;
            success = true;
        } else {
            success = false;
        }

        callback(success);
    }
}

Safari 확장은 구현하기 쉬웠습니다. 한 줄의 주입 스크립트로 구성되었습니다.

myinject.js :

window.postMessage("myappinstalled", window.location.origin);

그런 다음 웹 페이지 JavaScript에서 먼저 메시지 이벤트를 등록하고 메시지가 수신되면 플래그를 설정해야합니다.

window.addEventListener('message', function (msg) {
    if (msg.data === "myappinstalled") {
        myappinstalledflag = true;
    }
}, false);

이것은 사용자 정의 프로토콜과 관련된 응용 프로그램이 Safari 확장 설치를 관리한다고 가정합니다.

모든 경우에 콜백이 false를 반환하면 사용자에게 응용 프로그램 (즉, 사용자 지정 프로토콜)이 설치되지 않았 음을 알려야합니다.


IE에서는 작동하지 않습니다. 어떻게 작동해야하나요? 그 창 안에 정의 된 myWindow.location.href;iframe과 의 연결은 무엇 src입니까? 예외를 던져야합니까? 사용자 지정 프로토콜이 지원되는지 여부와 관계가 없습니다.
Burjua 2015-06-05

3

브라우저의 프로토콜 처리기를 감지해야한다고 말씀하셨습니다. 정말로 요?

sourceforge에서 파일을 다운로드하면 어떻게 되나요? myapp : // something을 열고 싶다고 가정 해 보겠습니다. 단순히 링크를 만드는 대신 HTTP를 통해 액세스하는 다른 HTML 페이지에 대한 링크를 만듭니다. 그런 다음 해당 페이지에서 해당 응용 프로그램을 열려고한다고 말합니다. 작동하지 않는 경우 애플리케이션을 설치해야하며 제공 할 링크를 클릭하면됩니다. 작동하면 모든 준비가 완료된 것입니다.


4
이것이 유용하지 않을 것이라고 제안하는 것은 도움이되지 않습니다. 시작 또는 다운로드 링크를 조건부로 표시하거나 링크를 클릭 할 때 조건부로 시작 또는 다운로드 할 수있는 것이 사용자에게 먼저 설치해야 함을 알리는 것보다 우수한 UX가 될 수 있다는 것이 분명해 보입니다.
StuartQ

3

다음과 같이 시도 할 수 있습니다.

function OpenCustomLink(link) {

    var w = window.open(link, 'xyz', 'status=0,toolbar=0,menubar=0,height=0,width=0,top=-10,left=-10');
    if(w == null) {            
        //Work Fine
    }
    else {
        w.close();
        if (confirm('You Need a Custom Program. Do you want to install?')) {
            window.location = 'SetupCustomProtocol.exe'; //URL for installer
        }
    }
}

아니요, Firefox 27에서는 작동하지 않습니다. (다른 브라우저에서는 테스트하지 않았습니다)
Blaise 2014 년

1
작동하지 않음-Windows 7, IE, Firefox, Opera, Chrome에서 테스트

1

비슷한 일을하려고하는데 Firefox에서 작동하는 트릭을 발견했습니다. IE의 트릭과 결합하면 두 가지 기본 브라우저에서 작동하는 하나를 가질 수 있습니다 (Safari에서 작동하는지 확실하지 않고 Chrome에서 작동하지 않는다는 것을 알고 있습니다)

if (navigator.appName=="Microsoft Internet Explorer" && document.getElementById("testprotocollink").protocolLong=="Unknown Protocol") {
    alert("No handler registered");
} else {
    try {
        window.location = "custom://stuff";
    } catch(err) {
        if (err.toString().search("NS_ERROR_UNKNOWN_PROTOCOL") != -1) {
            alert("No handler registered");
        }
    }
}

이것이 작동하려면 다음과 같이 페이지 어딘가에 숨겨진 링크가 있어야합니다.

<a id="testprotocollink" href="custom://testprotocol" style="display: none;">testprotocollink</a>

약간 해키하지만 작동합니다. 불행히도 Firefox 버전은 알 수없는 프로토콜로 링크를 방문하려고 할 때 표시되는 기본 경고를 계속 표시하지만 경고가 해제 된 후에 코드를 실행합니다.


1
"Firefox는이 주소를 여는 방법을 모릅니다. 프로토콜 (전화)이 어떤 프로그램과도 연결되어 있지 않기 때문에"라는 메시지가 계속 표시됩니다. catch 블록 앞의 메시지
Deebster

6
protocolLong은 "알려진"프로토콜 (file :, mailto :, gopher :, ftp :, http :, https :, news :)에 대한 결과 만 반환하고 다른 응용 프로그램 프로토콜에 대해서는 반환하지 않습니다.
EricLaw 2011 년

1

이것은 Microsoft 지원에서 IE에 권장되는 접근 방식이었습니다.

http://msdn.microsoft.com/en-us/library/ms537503%28VS.85%29.aspx#related_topics

"사용자 컴퓨터에 설치되는 바이너리를 제어 할 수있는 경우 스크립트에서 UA를 확인하는 것이 관련 접근 방식처럼 보입니다 : HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Internet Settings \ 5.0 \ User Agent \ Post Platform"- M $ 지원

모든 웹 페이지는 userAgent 문자열에 액세스 할 수 있으며 사용자 지정 포스트 플랫폼 값을 삭제하면 navigator.userAgent를 사용하여 자바 스크립트에서이를 감지하는 것은 매우 간단합니다.

다행히도 Firefox 및 Chrome과 같은 다른 주요 브라우저 (Safari :( 제외)는 사용자 정의 프로토콜이있는 링크를 클릭하고 프로토콜이 사용자 컴퓨터에 설치되어 있지 않을 때 "페이지를 찾을 수 없음"오류를 발생시키지 않습니다. IE는 여기서 매우 용서하지 않습니다. , 보이지 않는 프레임을 클릭하거나 자바 스크립트 오류를 ​​트랩하는 트릭이 작동하지 않고 "웹 페이지를 표시 할 수 없음"오류가 발생합니다. 우리가 사용하는 트릭은 브라우저 별 이미지를 사용하여 사용자에게 사용자 지정 프로토콜을 클릭하도록 알리는 것입니다. 링크를 클릭하면 응용 프로그램이 열립니다. 응용 프로그램이 열리지 않으면 "설치"페이지를 클릭 할 수 있습니다. XD 측면에서이 wprks는 IE의 ActiveX 접근 방식보다 낫습니다. FF 및 Chrome의 경우 계속 진행하십시오. 감지하지 않고 사용자 정의 프로토콜을 실행합니다. 사용자가보고있는 내용을 알려줍니다. Safari의 경우 :(아직 답변 없음


User-Agent 확장은 일반적이지만 문제가있는 접근 방식입니다. blogs.msdn.com/b/ieinternals/archive/2009/10/08/…
EricLaw

0

이것은 사소한 작업이 아닙니다. 한 가지 옵션은 레지스트리 및 / 또는 파일 시스템에 액세스하는 데 활용할 수있는 서명 된 코드를 사용하는 것입니다 ( 매우 비용이 많이 드는 옵션입니다). 또한 코드 서명을위한 통합 API 또는 사양이 없으므로 각 대상 브라우저에 대해 특정 코드를 생성해야합니다. 지원 악몽.

또한 게임 콘텐츠 전달 시스템 인 Steam에서도이 문제가 해결되지 않은 것 같습니다.


2
서명 된 코드는 custom : //을 처리하는 응용 프로그램과 함께 설치된 인증서로 서명되어야하므로 verisign과 같은 사람이 서명 한 값 비싼 응용 프로그램 인증서가 필요하지 않습니다.
WhyNotHugo

0

다음은 출시시 'phone home'으로 애플리케이션을 수정해야하는 또 다른 해키 답변입니다.

  1. 사용자가 링크를 클릭하여 애플리케이션을 시작합니다. 고유 식별자가 링크에 삽입되어 응용 프로그램이 시작될 때 전달됩니다. 웹 앱은 스피너 또는 그 특성을 보여줍니다.
  2. 그런 다음 웹 페이지는 동일한 고유 ID를 가진 앱에서 '애플리케이션 폰 홈'이벤트를 확인하기 시작합니다.
  3. 응용 프로그램이 시작되면 고유 식별자를 사용하여 웹 앱에 HTTP 게시를 수행하여 존재를 나타냅니다.
  4. 웹 페이지에서 응용 프로그램이 결국 시작된 것으로 보거나 '다운로드하십시오'페이지로 이동합니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.