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);
});
location.href = url;
setTimeout(function () {
elem.off('blur');
elem.removeAttr("tabindex");
if (!success) {
callback(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.