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

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

http://

mailto://

custom://

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

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

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

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



답변

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

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

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


답변

이를 수행하는 훌륭한 크로스 브라우저 방법은 없습니다. 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


답변

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


답변

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

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

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

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

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


답변

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

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

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/'


답변

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

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

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

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

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

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


답변

마침내 이것 과 매우 간단한 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를 반환하면 사용자에게 응용 프로그램 (즉, 사용자 지정 프로토콜)이 설치되지 않았 음을 알려야합니다.