ब्राउज़र के प्रोटोकॉल हैंडलर का पता कैसे लगाएं?


82

मैंने एक कस्टम URL प्रोटोकॉल हैंडलर बनाया है।

http://

mailto://

custom://

मैंने तदनुसार प्रतिक्रिया देने के लिए एक WinForms आवेदन पंजीकृत किया है। यह सब बहुत अच्छा काम करता है।

लेकिन मैं उस मामले को इनायत करने में सक्षम होना चाहूंगा जहां उपयोगकर्ता के पास कस्टम URL प्रोटोकॉल हैंडलर स्थापित नहीं है, फिर भी।

ऐसा करने में सक्षम होने के लिए मुझे ब्राउज़र के पंजीकृत प्रोटोकॉल हैंडलर का पता लगाने में सक्षम होना चाहिए, मैं जावास्क्रिप्ट से मानूंगा। लेकिन मुझे जानकारी के लिए मतदान करने का कोई तरीका नहीं मिल रहा है। मैं इस समस्या का हल खोजने की उम्मीद कर रहा हूं।

आपके द्वारा साझा किए जा सकने वाले किसी भी विचार के लिए धन्यवाद।


5
मुझे लगता है कि यह केवल क्रोम (यानी XPCOM, ActiveX, आदि) कोड में संभव होगा। अन्यथा, यह एक गोपनीयता मुद्दा होगा ("हमने पाया है कि आप यूडोरा का उपयोग करते हैं। आज ही फ्यूमाइल पर स्विच करें!")। लेकिन कृपया स्पष्ट करें कि आप किस ब्राउज़र (ओएस) / OS (es) में रुचि रखते हैं।
मैथ्यू फ्लशेन

1
अच्छी बात है, लेकिन मुझे यह जानकर ख़ुशी होगी कि मेरे मालिकाना प्रोटोकॉल को संभालने के लिए कुछ पंजीकृत है: // Windows IE, FireFox, और आदर्श रूप से सफारी
क्रिस क्राफ्ट

क्या आपने पहले से ही इस समस्या को हल कर लिया है?
jstuardo

जवाबों:


35

यह ऐसा करने के लिए एक बहुत , बहुत hacky तरीका होगा ... लेकिन क्या यह काम करेगा?

  • लिंक को सामान्य रूप में रखें ...
  • लेकिन इसके लिए एक ऑनक्लिक हैंडलर संलग्न करें, जो टाइमर सेट करता है और विंडो के लिए ऑनब्लर हैंडलर जोड़ता है
  • (सिद्धांत रूप में) यदि ब्राउज़र लिंक (एप्लीकेशन एक्स) को संभालता है, तो खिड़की से फोकस चोरी हो जाएगा ...
  • यदि onblur घटना आग, टाइमर साफ ...
  • अन्यथा 3-5 सेकंड में आपके टाइमआउट को आग लगने दें ... और उपयोगकर्ता को सूचित करें "हम्म, ऐसा लगता है कि आपके पास मेगा उबेर कूल एप्लीकेशन स्थापित नहीं है ... क्या आप इसे अभी स्थापित करना चाहेंगे? (ओके) (रद्द करें)"

बुलेटप्रूफ से दूर ... लेकिन यह मदद कर सकता है?


1
: D यह एक चतुर विचार है। लगता है कि वहाँ एक रास्ता होगा क्योंकि यह एक आम जरूरत की तरह लगता है।
क्रिस क्राफ्ट

2
मैक पर फ़ायरफ़ॉक्स (शायद अधिक ब्राउज़र) में, विंडो फ़ोकस खो देता है और ऑनब्लूर फायर हो जाता है, भले ही कस्टम प्रोटोकॉल वाला एप्लिकेशन लॉन्च करने में विफल हो।
क्वानो

यह क्रोम के लिए एक सभ्य समाधान है, क्योंकि इसमें प्रोटोकॉल के लिए किसी भी तरह की त्रुटि से निपटने की सुविधा नहीं है। : यह यहाँ अन्य ब्राउज़रों का पता लगाने के साथ संयोजन के रूप में इस्तेमाल किया गया rajeshsegu.com/2012/09/browser-detect-custom-protocols/...
Fillip पेयटन

प्रोटोकॉल का पता लगाना हाल ही में एक प्रमुख सिरदर्द रहा है। ;) उपरोक्त विधि कुछ हद तक काम करती लगती है ... rajeshsegu.com/fun/code/browser/detect.html पर मिले राजेश के जीवंत उदाहरण का उपयोग करके मैं क्रोम में "सच" हो रहा हूं। लेकिन अगर मैं रिफ्लेक्टर करता हूं ताकि कोई परिणाम न हो () फ़ंक्शन (जो बदले में एक अलर्ट बॉक्स का उपयोग करता है - एक अवरुद्ध कॉल) और इसे बस एक बूलियन वापस करने दें, मैं गलत हो रहा हूं। मुझे लगता है कि किसी भी तरह से अवरुद्ध चेतावनी भी किसी भी समय के लिए बाध्य करने के लिए एक हैक करने का तरीका है ... किसी भी अंतर्दृष्टि, @scunliffe?
ग्रेग पेटिट

यह विधि Chrome में काम करती है, सिवाय उस स्थिति में जब उपयोगकर्ता ने अपने उत्तर को याद रखने के लिए चुना, Win8 का उपयोग करके और उसके पास एप्लिकेशन नहीं है। इस मामले में धब्बा घटना तब भी होती है, जब अनुप्रयोग लॉन्च नहीं हो सकता है
पॉल हागोगो

18

ऐसा करने के लिए कोई महान क्रॉस-ब्राउज़र तरीका नहीं है। Win8 + पर IE10 + में, एक नया msLaunchUriएपीआई आपको एक प्रोटोकॉल लॉन्च करने में सक्षम बनाता है, जैसे:

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-platable-protocols-oh-my .aspx


यह काम नहीं करता है - विंडोज 7, IE ब्राउज़रों में परीक्षण किया गया

6
msLaunchUri केवल विंडोज 8+ है।
एरिकला जूल 7'14

लिंक मर चुका था।
किउलंग

16

HTML5 कस्टम स्कीम और सामग्री संचालकों को परिभाषित करता है (मेरी जानकारी के लिए फ़ायरफ़ॉक्स अब तक का एकमात्र कार्यान्वयनकर्ता है), लेकिन दुर्भाग्य से वर्तमान में यह जांचने का कोई तरीका नहीं है कि क्या कोई हैंडलर पहले से मौजूद है- यह प्रस्तावित किया गया है , लेकिन कोई अनुवर्ती नहीं था। यह कस्टम हैंडलर्स को प्रभावी ढंग से उपयोग करने के लिए एक महत्वपूर्ण विशेषता की तरह लगता है और इसे लागू करने के लिए डेवलपर्स को इस मुद्दे पर ध्यान देना चाहिए।


13

ऐसा लगता है कि जावास्क्रिप्ट के माध्यम से कोई सीधा रास्ता ऐसा नहीं है जो किसी ऐसे इंस्टॉल्ड ऐप की मौजूदगी का पता लगा सके जिसने प्रोटोकॉल हैंडलर पंजीकृत किया है।

आईट्यून्स मॉडल में, Apple अपने सर्वर को यूआरएल प्रदान करता है, जो तब कुछ जावास्क्रिप्ट चलाने वाले पृष्ठ प्रदान करता है:

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

तो आईट्यून्स इंस्टॉलर स्पष्ट रूप से प्रमुख ब्राउज़रों के लिए प्लगइन्स को तैनात करता है, जिनकी उपस्थिति का पता लगाया जा सकता है।

यदि आपका प्लगइन स्थापित है, तो आप यह सुनिश्चित कर सकते हैं कि आपके एप्लिकेशन-विशिष्ट url पर पुनर्निर्देशन सफल हो जाएगा।


2
यह सबसे विश्वसनीय समाधान होना चाहिए। लेकिन मेरा मतलब है कि आपको ज्यादातर ब्राउज़र के लिए एक प्लगइन स्थापित करने और बनाने की आवश्यकता है और यह एक तरह का मुश्किल काम है। इसके बजाय मैं उपयोगकर्ता को डाउनलोड पृष्ठ पर पुनर्निर्देशित करने में सक्षम होने के लिए अधिक उपयोगकर्ता-प्रिय हो सकता हूं।
नटिम

क्यों नहीं FireBreath का उपयोग कर के रूप में यहाँ उल्लेख किया है? stackoverflow.com/a/14758085/427793
swdev

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

कुकीज़ दैनिक साफ किया जा सकता है। क्या कोई बेहतर तरीका नहीं है कि आप फ्लैश आधारित कुकी बना सकें?

अगर कुकी को हटा दिया जाता है तो उपयोगकर्ता को फिर से संकेत दिया जाएगा।
नटिम

5

यदि आपके पास उस प्रोग्राम का नियंत्रण है जिसे आप (कोड) चलाने का प्रयास कर रहे हैं, तो यह देखने का एक तरीका है कि क्या उपयोगकर्ता एप्लिकेशन को चलाने में सफल रहा है:

  1. कस्टम प्रोटोकॉल को खोलने का प्रयास करने से पहले, एक सर्वर स्क्रिप्ट के लिए एक AJAX अनुरोध करें जो उपयोगकर्ता के इरादे को डेटाबेस में बचाता है (उदाहरण के लिए, उपयोगकर्ता को सहेजें और वह जो करना चाहता था)।

  2. प्रोग्राम को खोलने का प्रयास करें, और आशय डेटा पर पास करें।

  3. प्रोग्राम को सर्वर से डेटाबेस प्रविष्टि (सही पंक्ति को खोजने के इरादे डेटा का उपयोग करके) को हटाने के लिए अनुरोध करें।

  4. यह देखने के लिए कि डेटाबेस में प्रवेश हो गया है, जावास्क्रिप्ट को सर्वर पर कुछ समय के लिए रखें। यदि प्रविष्टि समाप्त हो गई है, तो आपको पता चल जाएगा कि उपयोगकर्ता एप्लिकेशन को खोलने में सफल रहा, अन्यथा प्रविष्टि बनी रहेगी (आप इसे बाद में साइटमैप के साथ हटा सकते हैं)।

मैंने यह तरीका आजमाया नहीं है, बस यह सोचा है।


4

मैं आखिरकार एक क्रॉस-ब्राउज़र (क्रोम 32, फ़ायरफ़ॉक्स 27, आईई 11, सफारी 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);
    }
}

सफारी एक्सटेंशन को लागू करना आसान था। इसमें इंजेक्शन स्क्रिप्ट की एक पंक्ति शामिल थी:

myinject.js:

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

फिर वेब पेज जावास्क्रिप्ट में, आपको सबसे पहले संदेश घटना को पंजीकृत करना होगा और संदेश प्राप्त होने पर एक झंडा लगाना होगा:

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

यह उस एप्लिकेशन को मानता है जो कस्टम प्रोटोकॉल से जुड़ा है, सफारी एक्सटेंशन की स्थापना का प्रबंधन करेगा।

सभी मामलों में, यदि कॉलबैक गलत है, तो आप उपयोगकर्ता को सूचित करना जानते हैं कि एप्लिकेशन (यानी, यह कस्टम प्रोटोकॉल है) स्थापित नहीं है।


यह IE के लिए काम नहीं करता है। यह कैसे काम करना है? उस विंडो के अंदर myWindow.location.href;और iframe के बीच क्या संबंध है src? क्या इसे अपवाद फेंकना चाहिए? यह इस बात की परवाह किए बिना नहीं है कि कस्टम प्रोटोकॉल समर्थित है या नहीं।
बुर्जुआ

3

आप कहते हैं कि आपको ब्राउज़र के प्रोटोकॉल हैंडलर का पता लगाने की आवश्यकता है - क्या आप वास्तव में हैं?

क्या होगा अगर आपने कुछ ऐसा किया है जब आप सोर्सफोर्ज से फाइल डाउनलोड करते हैं? मान लीजिए कि आप myapp खोलना चाहते हैं: // कुछ। बस इसका लिंक बनाने के बजाय, HTTP के माध्यम से एक्सेस किए गए दूसरे HTML पेज का लिंक बनाएं। फिर, उस पृष्ठ पर, कहें कि आप उनके लिए एप्लिकेशन खोलने का प्रयास कर रहे हैं। यदि यह काम नहीं करता है, तो उन्हें आपके एप्लिकेशन को इंस्टॉल करना होगा, जिसे वे आपके द्वारा प्रदान किए गए लिंक पर क्लिक करके कर सकते हैं। यदि यह काम करता है, तो आप सभी तैयार हैं।


4
यह सुझाव देना अनपेक्षित है कि यह उपयोगी नहीं होगा। मुझे यह स्पष्ट प्रतीत होता है कि किसी लॉन्च या डाउनलोड लिंक को सशर्त रूप से दिखाने में सक्षम होना - या यहां तक ​​कि सशर्त लॉन्च या डाउनलोड करना जब किसी लिंक पर क्लिक करना उपयोगकर्ता को यह बताने के लिए बेहतर UX होगा कि उन्हें पहले इंस्टॉल करने की आवश्यकता है।
स्टुअर्ट क्यू 9:15

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
        }
    }
}

नहीं, फ़ायरफ़ॉक्स 27 में काम नहीं करता है। (अन्य ब्राउज़रों में परीक्षण नहीं किया गया)
Blaise

1
काम नहीं करता - विंडोज 7, IE, फ़ायरफ़ॉक्स, ओपेरा, क्रोम में परीक्षण किया

1

मैं ऐसा ही कुछ करने की कोशिश कर रहा हूं और मैंने अभी-अभी एक ट्रिक खोजी है जो फ़ायरफ़ॉक्स के साथ काम करती है। यदि आप इसे IE के लिए ट्रिक के साथ जोड़ते हैं, तो आपके पास एक हो सकता है जो दोनों मुख्य ब्राउज़रों पर काम करता है (मुझे यकीन नहीं है कि यह सफारी में काम करता है और मुझे पता है कि यह क्रोम में काम नहीं करता है)

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>

यह थोड़ा हैकी है लेकिन यह काम करता है। फ़ायरफ़ॉक्स संस्करण दुर्भाग्य से अभी भी डिफ़ॉल्ट अलर्ट को पॉप अप करता है जो तब आता है जब आप किसी अज्ञात प्रोटोकॉल के साथ लिंक पर जाने की कोशिश करते हैं, लेकिन अलर्ट खारिज होने के बाद यह आपके कोड को चलाएगा।


1
मैंने पाया कि मुझे अभी भी "फ़ायरफ़ॉक्स पता नहीं है कि इस पते को कैसे खोला जाए, क्योंकि प्रोटोकॉल (टेली) किसी भी कार्यक्रम से जुड़ा नहीं है।" पकड़ ब्लॉक से पहले संदेश
Deebster

6
प्रोटोकॉललॉन्ग केवल "ज्ञात" प्रोटोकॉल (फ़ाइल:, mailto:, gopher:, ftp:, http:, https:, news :) और अन्य एप्लिकेशन प्रोटोकॉल के लिए परिणाम देता है।
20

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 \ उपयोगकर्ता / उपयोगकर्ता प्लेटफ़ॉर्म" - एम $ समर्थन द्वारा

हर वेब पेज के पास यूजरएग्रेंट स्ट्रिंग का उपयोग होता है और यदि आप एक कस्टम पोस्ट प्लेटफॉर्म वैल्यू को छोड़ देते हैं, तो यह पता लगाना कि जावास्क्रिप्ट में नेवीगेटर का उपयोग करना है।

सौभाग्य से, फ़ायरफ़ॉक्स और क्रोम जैसे अन्य प्रमुख ब्राउज़र (सफ़ारी को छोड़कर :(), कस्टम प्रोटोकॉल के साथ एक लिंक पर क्लिक किए जाने पर "पृष्ठ नहीं मिला" त्रुटियों को फेंक देते हैं और उपयोगकर्ता मशीन पर प्रोटोकॉल स्थापित नहीं होता है। IE यहां बहुत अक्षम है। , किसी अदृश्य फ्रेम या ट्रैप जावास्क्रिप्ट त्रुटियों में क्लिक करने की कोई ट्रिक काम नहीं करती है और बदसूरत "वेबपेज" को प्रदर्शित नहीं किया जा सकता है "त्रुटि। हमारे द्वारा उपयोग की जाने वाली ट्रिक हमारे उपयोगकर्ताओं को विशिष्ट प्रोटोकॉल पर क्लिक करने वाले ब्राउज़र विशिष्ट छवियों के साथ सूचित करने के लिए है। लिंक एक एप्लिकेशन को खोलेगा। और अगर उन्हें ऐप खोलने की जरूरत नहीं है, तो वे "इंस्टॉल" पेज पर क्लिक कर सकते हैं। XD के संदर्भ में यह wprks IE के लिए ActiveX दृष्टिकोण से बेहतर है। एफएफ और क्रोम के लिए, बस आगे बढ़ें। और बिना किसी पहचान के कस्टम प्रोटोकॉल लॉन्च करें। उपयोगकर्ता को बताएं कि वह क्या देखता है। सफारी के लिए:(अभी तक कोई जवाब नहीं


उपयोगकर्ता-एजेंट का विस्तार एक आम, लेकिन समस्याग्रस्त, दृष्टिकोण है। blogs.msdn.com/b/ieinternals/archive/2009/10/08/…
EricLaw

0

यह कोई तुच्छ कार्य नहीं है; एक विकल्प हस्ताक्षरित कोड का उपयोग करना हो सकता है, जिसका उपयोग आप रजिस्ट्री और / या फाइल सिस्टम तक पहुँचने के लिए कर सकते हैं (कृपया ध्यान दें कि यह एक बहुत महंगा विकल्प है)। कोड पर हस्ताक्षर करने के लिए कोई एकीकृत एपीआई या विनिर्देश भी नहीं है, इसलिए आपको प्रत्येक लक्ष्य ब्राउज़र के लिए विशिष्ट कोड उत्पन्न करना होगा। एक बुरा सपना।

इसके अलावा, मुझे पता है कि गेमिंग सामग्री वितरण प्रणाली स्टीम , इस समस्या को या तो हल नहीं करती है।


2
हस्ताक्षरित कोड को एक प्रमाण पत्र द्वारा हस्ताक्षरित किया जाना चाहिए जो कि कस्टम को संभालने वाले एप्लिकेशन के साथ स्थापित किया गया है: // ताकि कोई वास्तविक रूप से महंगे आवेदन प्रमाण पत्र की आवश्यकता न हो, जैसे किसी व्यक्ति द्वारा हस्ताक्षर किए गए।
WhyNotHugo

0

यहां एक और हैकरी जवाब है जिसे लॉन्च पर 'फोन होम' में आपके आवेदन के लिए (उम्मीद है कि प्रकाश) संशोधन की आवश्यकता होगी।

  1. उपयोगकर्ता क्लिक लिंक, जो अनुप्रयोग लॉन्च करने का प्रयास करता है। एक विशिष्ट पहचानकर्ता को लिंक में डाल दिया जाता है, ताकि लॉन्च होने पर इसे एप्लिकेशन को पास कर दिया जाए। वेब ऐप एक स्पिनर या उस प्रकृति का कुछ दिखाता है।
  2. वेब पेज तब इसी यूनिक आईडी वाले ऐप से 'एप्लिकेशन फोन होम' ईवेंट के लिए जांचना शुरू करता है।
  3. जब लॉन्च किया जाता है, तो आपका एप्लिकेशन उपस्थिति को इंगित करने के लिए, अद्वितीय पहचानकर्ता के साथ आपके वेब ऐप पर एक HTTP पोस्ट करता है।
  4. या तो वेब पेज देखता है कि एप्लिकेशन लॉन्च हुआ, अंततः, या 'कृपया डाउनलोड करें' पेज के साथ आगे बढ़ता है।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.