探索浏览器与本地应用无缝连接的多种技术方案
chrome打开外部app是指通过chrome浏览器启动或调用安装在用户计算机上的本地应用程序。这种技术让网页能够与桌面应用进行交互,大大扩展了web应用的功能边界。
用户可以直接从网页快速启动熟悉的桌面应用,无需手动查找和打开。
实现web应用与桌面应用的数据同步和功能互补。
减少用户操作步骤,自动化工作流程。
url scheme是最简单直接的方案,通过自定义协议来启动外部应用。
url scheme类似于http://、https://,但是是自定义的协议前缀,如myapp://、mailto:等。
window.location.href = 'myapp://action?data=somedata';
mailto:someone@example.com
tel: 1234567890
spotify:track:1234567890
slack://channel?team=t12345&id=c1234567890
vscode://file/full/path/to/file
通过开发chrome扩展,可以实现更强大和安全的本地应用调用功能。
{
"name": "app launcher",
"version": "1.0",
"manifest_version": 3,
"permissions": [
"nativemessaging"
],
"background": {
"service_worker": "background.js"
},
"externally_connectable": {
"matches": ["*://*.example.com/*"]
}
}
chrome.runtime.onmessage.addlistener(
function(request, sender, sendresponse) {
if (request.action === "launchapp") {
chrome.runtime.sendnativemessage(
'com.example.app',
{ "text": "hello from extension" },
function(response) {
console.log(response);
}
);
}
}
);
native messaging是chrome提供的官方机制,允许扩展与本地应用进行双向通信。
{
"name": "com.example.app",
"description": "example app host",
"path": "c:\\program files\\exampleapp\\host.exe",
"type": "stdio",
"allowed_origins": [
"chrome-extension://[extension_id]/"
]
}
import sys
import json
import struct
def send_message(message_content):
encoded_content = json.dumps(message_content).encode('utf-8')
encoded_length = struct.pack('@i', len(encoded_content))
sys.stdout.buffer.write(encoded_length)
sys.stdout.buffer.write(encoded_content)
sys.stdout.buffer.flush()
while true:
text_length_bytes = sys.stdin.buffer.read(4)
if len(text_length_bytes) == 0:
break
text_length = struct.unpack('@i', text_length_bytes)[0]
text = sys.stdin.buffer.read(text_length).decode('utf-8')
message = json.loads(text)
if message.get('action') == 'launch':
# 启动应用逻辑
send_message({'status': 'success'})
pwa提供了另一种集成方式,通过web app manifest和service worker实现类原生体验。
{
"name": "my pwa app",
"short_name": "myapp",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#667eea",
"icons": [
{
"src": "icon-192.png",
"sizes": "192x192",
"type": "image/png"
}
],
"protocol_handlers": [
{
"protocol": "web myapp",
"url": "/handler?%s"
}
]
}
self.addeventlistener('fetch', event => {
if (event.request.url.startswith('web myapp://')) {
event.respondwith(
new response('handling custom protocol', {
status: 200,
headers: { 'content-type': 'text/plain' }
})
);
}
});
一套代码多端运行,包括桌面和移动设备
通过service worker实现离线功能
用户可以像安装原生应用一样安装pwa
以下是一些实际的应用示例,展示不同场景下的实现方案。
// 检测并调用邮件客户端
function launchemailclient(email) {
const mailtolink = `mailto:${email}`;
window.location.href = mailtolink;
// 检测是否成功打开
settimeout(() => {
if (document.hasfocus()) {
alert('未检测到邮件客户端,请手动打开');
}
}, 500);
}
// 调用vlc播放器
function playinvlc(videourl) {
const vlcprotocol = `vlc://${videourl}`;
// 尝试多种播放器
const players = [
`vlc://${videourl}`,
`potplayer://${videourl}`,
`mpv://${videourl}`
];
players.foreach(player => {
const iframe = document.createelement('iframe');
iframe.style.display = 'none';
iframe.src = player;
document.body.appendchild(iframe);
settimeout(() => document.body.removechild(iframe), 100);
});
}
// vs code集成
function openinvscode(filepath, line = 1) {
const vscodeurl = `vscode://file/${filepath}:${line}`;
window.open(vscodeurl, '_blank');
}
// webstorm集成
function openinwebstorm(projectpath) {
const webstormurl = `webstorm://open?file=${projectpath}`;
window.location.href = webstormurl;
}