跳转到内容

Contact Picker API:让用户分享选定的联系人,而非整个通讯录

发布于

一句话: Contact Picker API 让 web 应用通过浏览器原生的选择器界面,请求用户从通讯录中挑选一个或多个联系人——只分享用户选中的具体联系人和字段,绝不会分享完整通讯录。

Contact Picker API 允许用户从其联系人列表中选择条目,并将所选条目的有限详情分享给网站 或应用。navigator.contacts 暴露一个 ContactsManager,ContactsManager.select() 会 打开一个由浏览器控制的选择器;用户决定选择哪些联系人,以及释放所请求的哪些属性 (name、email、tel、address、icon)。MDN 列出的常见用例包括:选择要通过邮件或 聊天应用联系的联系人、为 VOIP 通话选择联系人的电话号码,或发现哪些联系人已在使用某个 社交平台。

const props = ['name', 'email', 'tel'];
const opts = { multiple: true };
async function getContacts() {
try {
const contacts = await navigator.contacts.select(props, opts);
handleResults(contacts);
} catch (ex) {
// select() 可能抛出异常——见下方「可能出错的地方」。
}
}

props 列出要请求的字段;getProperties() 会报告当前浏览器实际支持这些字段中的哪些, 让网站在调用 select() 之前调整请求:

async function checkProperties() {
const supported = await navigator.contacts.getProperties();
if (supported.includes('email')) {
// 可以安全地在 props 中请求 "email"。
}
}
  • 安全上下文。 MDN 记载 select() 仅在安全上下文(HTTPS)中可用。
  • 用户手势。 MDN 说明 select() 需要用户手势,返回的 Promise 才会 resolve。
  • 不适用于 Web Worker。 MDN 指出 Contact Picker API 不会暴露在 WorkerNavigator 上。

MDN 将 Contact Picker API 标记为实验性技术,不属于 Baseline,因为它无法在一些最广泛使用 的浏览器中运行。在生产环境中依赖它之前,请查阅 MDN 上 Contact_Picker_API 与 ContactsManager 页面的浏览器兼容性表。

async function shareContacts(props, opts) {
if (!('contacts' in navigator && 'ContactsManager' in window)) {
// 此处不支持——回退到手动输入表单。
return null;
}
return navigator.contacts.select(props, opts);
}

MDN 的 select() 参考文档记载了该调用可能抛出/拒绝的错误条件:

  • TypeError —— 请求的 properties 列表为空,或包含浏览器不支持的属性。
  • InvalidStateError —— 调用发生在非顶层浏览上下文中、已有一个联系人选择器处于打开 状态,或选择器本身启动失败。
  • SecurityError —— select() 并非由用户激活触发。

MDN 自己的示例用 try/catch 来处理这些情况;由于 select() 返回一个 Promise,也可以 用 .catch() 处理。

  • 在调用 select() 之前,先用 'contacts' in navigator && 'ContactsManager' in window 做特性检测。
  • 只在真实的用户手势中调用 select()——MDN 记载它需要用户手势才能 resolve。
  • 在依赖返回字段之前,先调用 getProperties() 确认浏览器实际会返回哪些字段。
  • 处理 TypeError、InvalidStateError、SecurityError——可以用 try/catch,也 可以对返回的 Promise 使用 .catch()。
  • 准备好手动输入的回退界面——MDN 将该 API 标记为非 Baseline。
  • 不要假设访问权限会持续存在——每次请求都需要用户重新执行一次操作。