Làm cách nào để phát hiện trình xử lý giao thức của trình duyệt?


82

Tôi đã tạo một trình xử lý giao thức URL tùy chỉnh.

http://

mailto://

custom://

Tôi đã đăng ký một ứng dụng WinForms để phản hồi tương ứng. Tất cả điều này hoạt động tuyệt vời.

Nhưng tôi muốn có thể xử lý khéo léo trường hợp người dùng chưa cài đặt trình xử lý giao thức URL tùy chỉnh.

Để có thể làm được điều này, tôi cần có khả năng phát hiện các trình xử lý giao thức đã đăng ký của trình duyệt, tôi sẽ giả sử từ JavaScript. Nhưng tôi đã không thể tìm ra cách để thăm dò thông tin. Tôi hy vọng sẽ tìm thấy một giải pháp cho vấn đề này.

Cảm ơn vì bất kỳ ý tưởng nào bạn có thể chia sẻ.


5
Tôi nghĩ rằng điều này sẽ chỉ có thể thực hiện được trong mã chrome (tức là XPCOM, ActiveX, v.v.). Nếu không, đó sẽ là vấn đề về quyền riêng tư ("Chúng tôi đã phát hiện thấy bạn sử dụng Eudora. Hãy chuyển sang FooMail ngay hôm nay!"). Nhưng vui lòng làm rõ (các) trình duyệt / (các) hệ điều hành mà bạn quan tâm.
Matthew Flaschen

1
Tốt thôi, nhưng tôi rất vui khi biết một số thứ đã được đăng ký để xử lý giao thức độc quyền của tôi acsfs: // Windows IE, FireFox và lý tưởng là Safari
Chris Craft

Bạn đã giải quyết được vấn đề này chưa?
jstuardo

Câu trả lời:


35

Đây sẽ là một rất , rất hacky cách để làm điều này ... nhưng sẽ làm việc này?

  • Đặt liên kết vào bình thường ...
  • Nhưng hãy đính kèm một trình xử lý onclick vào nó để đặt bộ đếm thời gian và thêm một trình xử lý onblur cho cửa sổ
  • (về lý thuyết) nếu trình duyệt xử lý liên kết (ứng dụng X) sẽ tải lấy tiêu điểm từ cửa sổ ...
  • Nếu sự kiện onblur kích hoạt, hãy xóa bộ hẹn giờ ...
  • Nếu không, trong 3-5 giây, hãy để thời gian chờ của bạn kích hoạt ... và thông báo cho người dùng "Rất tiếc, có vẻ như bạn chưa cài đặt Ứng dụng Mega Uber Cool ... bạn có muốn cài đặt ngay không? (Ok) (Hủy)"

Khác xa với chống đạn ... nhưng nó có thể giúp ích?


1
: D Đó là một ý tưởng thông minh. Có vẻ như sẽ có một cách vì nó dường như là một nhu cầu chung.
Chris Craft

2
Trong Firefox trên Mac (có thể có nhiều trình duyệt hơn), cửa sổ bị mất tiêu điểm và bật tắt mặc dù ứng dụng có giao thức tùy chỉnh không khởi chạy được.
quano

Đây là một giải pháp tốt cho Chrome, vì nó không có bất kỳ loại xử lý lỗi nào cho các giao thức. Điều này đã được sử dụng cùng với việc phát hiện các trình duyệt khác tại đây: rajeshsegu.com/2012/09/browser-detect-custom-protocols/…
Fillip Peyton

phát hiện giao thức đã là một vấn đề đau đầu gần đây. ;) Phương pháp trên có vẻ hoạt động đôi chút ... bằng cách sử dụng ví dụ trực tiếp của rajesh được tìm thấy tại rajeshsegu.com/fun/code/browser/detect.html Tôi đang đưa "true" vào Chrome. Nhưng nếu tôi cấu trúc lại để không có hàm results () (hàm này sử dụng một hộp cảnh báo - một lệnh gọi chặn) và để nó chỉ trả về một boolean, thì tôi nhận được sai. Tôi cảm thấy bằng cách nào đó rằng cảnh báo chặn cũng là một cách hacky để buộc thời gian bằng cách nào đó ... bất kỳ thông tin chi tiết nào, @scunliffe?
Greg Pettit

Phương pháp này hoạt động trong Chrome, ngoại trừ trường hợp người dùng đã chọn ghi nhớ câu trả lời của họ, sử dụng Win8 và không có ứng dụng. Trong trường hợp này, sự kiện mờ xảy ra ngay cả khi ứng dụng không thể khởi chạy
Paul Haggo

18

Không có cách nào tuyệt vời trên nhiều trình duyệt để làm điều này. Trong IE10 + trên Win8 +, một msLaunchUriapi mới cho phép bạn khởi chạy một giao thức, như sau:

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

Nếu giao thức không được cài đặt, lệnh gọi lại thất bại sẽ kích hoạt. Nếu không, giao thức sẽ khởi chạy và lệnh gọi lại thành công sẽ kích hoạt.

Tôi thảo luận về chủ đề này xa hơn một chút ở đây: http://blogs.msdn.com/b/ieinternals/archive/2011/07/14/url-protocols-application-protocols-and-asynchronous-pluggable-protocols-oh-my .aspx


Nó không làm việc - thử nghiệm trong Windows 7, trình duyệt IE

6
msLaunchUri chỉ dành cho Windows 8+.
EricLaw

Liên kết đã chết.
Qiulang

16

HTML5 xác định lược đồ tùy chỉnh và trình xử lý nội dung (theo hiểu biết của tôi, Firefox là trình triển khai duy nhất cho đến nay), nhưng tiếc là hiện tại không có cách nào để kiểm tra xem trình xử lý đã tồn tại chưa — nó đã được đề xuất , nhưng không có theo dõi. Đây có vẻ như là một tính năng quan trọng để sử dụng trình xử lý tùy chỉnh một cách hiệu quả và chúng tôi với tư cách là nhà phát triển nên chú ý đến vấn đề này để triển khai nó.


13

Dường như không có cách nào dễ dàng thông qua javascript để phát hiện sự hiện diện của một ứng dụng được cài đặt đã đăng ký trình xử lý giao thức.

Trong mô hình iTunes, Apple cung cấp url cho máy chủ của họ, sau đó cung cấp các trang chạy một số javascript:

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

Vì vậy, trình cài đặt iTunes dường như triển khai các plugin cho các trình duyệt chính, sau đó có thể phát hiện sự hiện diện của chúng.

Nếu plugin của bạn đã được cài đặt, thì bạn có thể chắc chắn một cách hợp lý rằng việc chuyển hướng đến url dành riêng cho ứng dụng của bạn sẽ thành công.


2
Đây phải là giải pháp đáng tin cậy nhất. Nhưng tôi có nghĩa là bạn cần phải cài đặt và cũng tạo một plugin cho hầu hết các trình duyệt và điều đó khá phức tạp. Tôi có thể thân thiện hơn với người dùng để có thể chuyển hướng người dùng đến trang tải xuống.
Natim

Tại sao không sử dụng FireBreath như đã đề cập ở đây? stackoverflow.com/a/14758085/427793
swdev

10

Giải pháp dễ dàng nhất là hỏi người sử dụng lần đầu tiên.

Sử dụng hộp thoại xác nhận Javascript cho mỗi ví dụ:

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

Cookies có thể được loại bỏ sạch sẽ hàng ngày. Không có cách nào tốt hơn bạn có thể tạo cookie dựa trên Flash?

Nếu cookie bị xóa, người dùng sẽ được nhắc lại.
Natim

5

Nếu bạn có quyền kiểm soát chương trình bạn đang cố chạy (mã), một cách để xem liệu người dùng có chạy ứng dụng thành công hay không là:

  1. Trước khi cố gắng mở giao thức tùy chỉnh, hãy thực hiện yêu cầu AJAX tới tập lệnh máy chủ lưu ý định của người dùng trong cơ sở dữ liệu (ví dụ: lưu userid và những gì anh ta muốn làm).

  2. Cố gắng mở chương trình và chuyển dữ liệu ý định.

  3. Yêu cầu chương trình thực hiện yêu cầu máy chủ xóa mục nhập cơ sở dữ liệu (sử dụng dữ liệu ý định để tìm đúng hàng).

  4. Thực hiện cuộc thăm dò javascript trên máy chủ trong một thời gian để xem liệu mục cơ sở dữ liệu đã biến mất chưa. Nếu mục nhập bị biến mất, bạn sẽ biết người dùng đã mở ứng dụng thành công, nếu không mục nhập sẽ vẫn còn (bạn có thể xóa nó sau bằng cronjob).

Tôi chưa thử phương pháp này, chỉ nghĩ thôi.


4

Cuối cùng tôi đã có thể nhận được một giải pháp trình duyệt chéo (Chrome 32, Firefox 27, IE 11, Safari 6) hoạt động với sự kết hợp của điều này và một tiện ích mở rộng Safari siêu đơn giản. Phần lớn giải pháp này đã được đề cập theo cách này hay cách khác trong câu hỏi này và câu hỏi khác .

Đây là kịch bản:

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

Tiện ích mở rộng Safari rất dễ thực hiện. Nó bao gồm một dòng lệnh chèn:

myinject.js:

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

Sau đó, trong JavaScript của trang web, trước tiên bạn cần đăng ký sự kiện tin nhắn và đặt cờ nếu nhận được tin nhắn:

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

Điều này giả định rằng ứng dụng được liên kết với giao thức tùy chỉnh sẽ quản lý việc cài đặt tiện ích mở rộng Safari.

Trong mọi trường hợp, nếu lệnh gọi lại trả về false, bạn phải thông báo cho người dùng rằng ứng dụng (tức là giao thức tùy chỉnh) chưa được cài đặt.


Nó không hoạt động cho IE. Làm thế nào nó được cho là hoạt động? kết nối giữa myWindow.location.href;và iframe srcđược xác định bên trong cửa sổ đó là gì? Nó có phải là để ném một ngoại lệ? Nó không phụ thuộc vào việc giao thức tùy chỉnh có được hỗ trợ hay không.
Burjua

3

Bạn nói rằng bạn cần phát hiện trình xử lý giao thức của trình duyệt - bạn có thực sự không?

Điều gì sẽ xảy ra nếu bạn làm điều gì đó giống như điều gì xảy ra khi bạn tải xuống một tệp từ sourceforge? Giả sử bạn muốn mở myapp: // cái gì đó. Thay vì chỉ tạo một liên kết đến nó, hãy tạo một liên kết đến một trang HTML khác được truy cập qua HTTP. Sau đó, trên trang đó, hãy nói rằng bạn đang cố gắng mở ứng dụng cho họ. Nếu nó không hoạt động, họ cần cài đặt ứng dụng của bạn, họ có thể thực hiện bằng cách nhấp vào liên kết mà bạn sẽ cung cấp. Nếu nó hoạt động, thì bạn đã sẵn sàng.


4
Thật vô ích khi gợi ý rằng điều này sẽ không hữu ích. Đối với tôi, có vẻ như hiển thị có điều kiện liên kết khởi chạy hoặc tải xuống - hoặc thậm chí khởi chạy hoặc tải xuống có điều kiện khi nhấp vào liên kết sẽ là một trải nghiệm tuyệt vời hơn khi nói với người dùng rằng họ cần cài đặt trước.
StuartQ

3

Bạn có thể thử một cái gì đó như sau:

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

Không, không làm việc trong Firefox 27. (Chẳng phải kiểm tra trong các trình duyệt khác)
Blaise

1
Không hoạt động - thử nghiệm trong Windows 7, trình duyệt IE, Firefox, Opera, Chrome

1

Tôi đang cố gắng làm điều gì đó tương tự và tôi vừa phát hiện ra một thủ thuật hoạt động với Firefox. Nếu bạn kết hợp nó với thủ thuật dành cho IE, bạn có thể có một thủ thuật hoạt động trên cả hai trình duyệt chính (Tôi không chắc liệu nó có hoạt động trong Safari hay không và tôi biết nó không hoạt động trong 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");
        }
    }
}

Để điều này hoạt động, bạn cũng cần có một liên kết ẩn ở đâu đó trên trang, như sau:

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

Nó hơi hacky nhưng nó hoạt động. Rất tiếc, phiên bản Firefox vẫn bật lên cảnh báo mặc định xuất hiện khi bạn cố gắng truy cập vào một liên kết có giao thức không xác định, nhưng nó sẽ chạy mã của bạn sau khi cảnh báo bị loại bỏ.


1
Tôi thấy rằng tôi vẫn nhận được thông báo "Firefox không biết cách mở địa chỉ này, vì giao thức (tel) không được liên kết với bất kỳ chương trình nào." tin nhắn trước khối bắt
Deebster

6
protocolLong chỉ trả về kết quả cho các giao thức "đã biết" (file:, mailto:, gopher :, ftp :, http:, https:, news :) và không trả về các Giao thức Ứng dụng khác.
EricLaw

1

Đây là cách tiếp cận được đề xuất cho IE bởi bộ phận hỗ trợ của Microsoft

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

"Nếu bạn có một số quyền kiểm soát đối với các tệp nhị phân đang được cài đặt trên máy của người dùng, kiểm tra UA trong tập lệnh có vẻ như là một cách tiếp cận phù hợp: HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Internet Settings \ 5.0 \ User Agent \ Post Platform" - Bởi M $ hỗ trợ

Mọi trang web đều có quyền truy cập vào chuỗi userAgent và nếu bạn giảm giá trị nền tảng bài đăng tùy chỉnh, việc phát hiện điều này trong javascript bằng cách sử dụng Navigator.userAgent khá đơn giản.

May mắn thay, các trình duyệt chính khác như Firefox và Chrome (chặn Safari :(), không gây ra lỗi "không tìm thấy trang" khi nhấp vào liên kết với giao thức tùy chỉnh và giao thức không được cài đặt trên máy người dùng. IE rất không thể tha thứ ở đây , bất kỳ thủ thuật nào để nhấp vào khung ẩn hoặc bẫy lỗi javascript không hoạt động và kết thúc với lỗi "trang web không thể hiển thị" xấu xí. Thủ thuật mà chúng tôi sử dụng trong trường hợp của mình là thông báo cho người dùng bằng hình ảnh cụ thể của trình duyệt rằng nhấp vào giao thức tùy chỉnh liên kết sẽ mở một ứng dụng. Và nếu họ không tìm thấy ứng dụng đang mở, họ có thể nhấp vào trang "cài đặt". Về mặt XD, cách này wprks tốt hơn so với cách tiếp cận ActiveX dành cho IE. Đối với FF và Chrome, hãy tiếp tục và khởi chạy giao thức tùy chỉnh mà không bị phát hiện. Cho phép người dùng cho bạn biết những gì họ nhìn thấy. Đối với Safari,:(chưa có câu trả lời


Tiện ích mở rộng tác nhân người dùng là một cách tiếp cận phổ biến, nhưng có vấn đề. blogs.msdn.com/b/ieinternals/archive/2009/10/08/...
EricLaw

0

Đây không phải là một nhiệm vụ tầm thường; một tùy chọn có thể là sử dụng mã đã ký, mà bạn có thể tận dụng để truy cập vào sổ đăng ký và / hoặc hệ thống tệp (xin lưu ý rằng đây là một tùy chọn rất tốn kém ). Cũng không có API hoặc thông số kỹ thuật thống nhất để ký mã, vì vậy bạn sẽ được yêu cầu tạo mã cụ thể cho từng trình duyệt mục tiêu. Một cơn ác mộng hỗ trợ.

Ngoài ra, tôi biết rằng Steam , hệ thống phân phối nội dung trò chơi, dường như cũng không giải quyết được vấn đề này.


2
Mã đã ký phải được ký bởi một chứng chỉ được cài đặt cùng với ứng dụng xử lý tùy chỉnh: // vì vậy sẽ không cần một chứng chỉ ứng dụng thực sự đắt tiền được ký bởi một người như verisign.
WhyNotHugo

0

Đây là một câu trả lời khó hiểu khác sẽ yêu cầu sửa đổi (hy vọng là nhẹ) đối với ứng dụng của bạn thành 'điện thoại nhà' khi khởi chạy.

  1. Người dùng nhấp vào liên kết, cố gắng khởi chạy ứng dụng. Một số nhận dạng duy nhất được đưa vào liên kết để nó được chuyển đến ứng dụng khi nó khởi chạy. Ứng dụng web hiển thị một con quay hoặc thứ gì đó tương tự.
  2. Sau đó, trang web bắt đầu kiểm tra sự kiện 'trang chủ điện thoại ứng dụng' từ một ứng dụng có cùng ID duy nhất này.
  3. Khi khởi chạy, ứng dụng của bạn thực hiện một bài đăng HTTP lên ứng dụng web của bạn với số nhận dạng duy nhất, để biểu thị sự hiện diện.
  4. Trang web thấy rằng cuối cùng ứng dụng đã khởi chạy hoặc chuyển sang trang 'vui lòng tải xuống'.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.