本文翻譯自 Read Phone Contacts with JavaScript,作者:Alvaro Montoro, 略有刪改。

作者注:本文中描述的技術(shù)和流程是實(shí)驗(yàn)性的,只能在少數(shù)瀏覽器中工作。在撰寫本文時(shí),聯(lián)系人選擇器API僅支持 Android Chrome(從版本80開(kāi)始)和iOS Safari(從版本14.5開(kāi)始)。如果要檢查是否可使用這個(gè)功能,可以訪問(wèn)這個(gè)演示網(wǎng)站alvaromontoro.com/demos/contacts/
體驗(yàn)。
在以前使用JavaScript從手機(jī)訪問(wèn)聯(lián)系人數(shù)據(jù)是不可想象的?,F(xiàn)在有了聯(lián)系人選擇器API,我們可以使用JavaScript來(lái)實(shí)現(xiàn)這個(gè)功能。
此功能在需要聯(lián)系人信息(如電話號(hào)碼或VoIP)的應(yīng)用程序,通過(guò)這個(gè)功能我們可以在社交平臺(tái)中發(fā)現(xiàn)通訊錄中的好友(前提需要社交平臺(tái)有對(duì)應(yīng)的手機(jī)號(hào)碼字段),或者需要填寫聯(lián)系人表單信息時(shí)則無(wú)需切換應(yīng)用程序即可獲取到相應(yīng)的數(shù)據(jù)。
API和設(shè)備將限制可用的屬性。開(kāi)發(fā)者可以選擇以下五個(gè)標(biāo)準(zhǔn)屬性:
以上返回的都是數(shù)組形式,因?yàn)槁?lián)系人可以有多個(gè)電話、電子郵件或多個(gè)地址。為了保持一致性,即使它是單個(gè)值,返回的數(shù)據(jù)始終是一個(gè)數(shù)組。
隱私和安全
存儲(chǔ)在手機(jī)上的聯(lián)系人信息可能包含敏感信息,我們必須小心處理。我們需要必須考慮到隱私和安全問(wèn)題:
聯(lián)系人選擇器API代碼必須在頂級(jí)瀏覽上下文中運(yùn)行。 它防止外部代碼,如廣告或第三方插件,讀取手機(jī)上的聯(lián)系人列表。
聯(lián)系人選擇器API代碼只能在用戶手勢(shì)后運(yùn)行。 開(kāi)發(fā)者不能完全自動(dòng)化這個(gè)過(guò)程,用戶必須采取行為觸發(fā)后讀取聯(lián)系人。
用戶必須允許訪問(wèn)聯(lián)系人列表。 這個(gè)是由手機(jī)限制而不是JavaScript強(qiáng)加的。用戶必須授予瀏覽器訪問(wèn)聯(lián)系人的權(quán)限(如果它還沒(méi)有授權(quán))。
當(dāng)他們第一次使用使用聯(lián)系人選擇器API的網(wǎng)站時(shí),他們可能會(huì)收到這樣的提示:

手機(jī)會(huì)在每次使用聯(lián)系人選擇器API代碼時(shí)顯示這個(gè)彈出窗口,直到用戶點(diǎn)擊“允許”。聯(lián)系人選擇器API在未允許之前不會(huì)運(yùn)行。這個(gè)一次性的,授權(quán)之后不會(huì)再?gòu)棾觥?/p>
API和代碼
聯(lián)系人選擇器API只定義了兩個(gè)方法:
getProperties()
:返回設(shè)備上可讀取的屬性列表。在定義中有五個(gè)值:"address
"(地址)、"email
"(電子郵件)、"icon
"(這可能不是聯(lián)系人圖片)、"name
"(姓名)、"tel
"(電話),但設(shè)備可能不允許訪問(wèn)所有這些屬性。
select()
:打開(kāi)聯(lián)系人彈出窗口,并在用戶完成操作后返回選擇。它接受兩個(gè)參數(shù):要讀取的屬性列表和一個(gè)可選的對(duì)象,包含選項(xiàng)。
兩種方法都返回Promise
,但考慮到它們觸發(fā)的操作會(huì)阻止應(yīng)用程序的正常流程,我們?cè)谔幚硭鼈儠r(shí)應(yīng)該使用async / await
。
如前面隱私和安全部分所述,在調(diào)用API之前需要用戶操作,因此如果沒(méi)有用戶交互,我們就無(wú)法觸發(fā)任何內(nèi)容,因此我們新增一個(gè)按鈕:
<button onclick="getContactData()">Show contact data</button>
主要的代碼將在getContactData()
函數(shù)中。但在此之前如果聯(lián)系人選擇器API不可用,顯示按鈕沒(méi)有意義,在默認(rèn)情況下隱藏按鈕(添加hidden屬性),僅在API可用時(shí)才顯示它。通過(guò) "contacts" in navigator
判斷當(dāng)前瀏覽器環(huán)境是否支持該API:
if ("contacts" in navigator) {
document.querySelector("button").removeAttribute("hidden");
}
接下來(lái)是核心的按鈕邏輯:
async function getContactData() {
// 指定將讀取哪些聯(lián)系人值
const props = ["tel", "name", "email"];
try {
// 打開(kāi)本地聯(lián)系人選擇器(在權(quán)限被授予后)
const contacts = await navigator.contacts.select(props);
// 這將在本地聯(lián)系人選擇器關(guān)閉后執(zhí)行
if (contacts.length) {
// 如果有數(shù)據(jù),顯示
alert("選中的數(shù)據(jù): " + JSON.stringify(contacts));
} else {
// 沒(méi)有表示沒(méi)有選擇
alert("沒(méi)有選擇任何內(nèi)容");
}
} catch (ex) {
// 如果發(fā)生錯(cuò)誤,顯示錯(cuò)誤信息
alert(ex.message)
}
}
一旦按鈕觸發(fā)了這個(gè)功能,如果瀏覽器有權(quán)限,聯(lián)系人選擇頁(yè)將會(huì)顯示出來(lái),展示基本信息:閱讀數(shù)據(jù)的URL,它將返回什么數(shù)據(jù),以及要從中挑選的聯(lián)系人列表。

關(guān)閉彈窗后,contacts
變量將以JSON格式存儲(chǔ)數(shù)據(jù),作為一個(gè)數(shù)組,其中包含所請(qǐng)求信息的對(duì)象(如果聯(lián)系人卡片中不可用,則可能為空)。
這是選擇了聯(lián)系人后的結(jié)果示例:
[ { "address": [], "email": [ "alvarosemail@gmail.com" ], "icon": [], "name": [ "Alvaro Montoro" ], "tel": [ "555-555-5555", "555-123-4567" ] } ]
如果數(shù)據(jù)包含圖標(biāo),則它將是帶有圖像的blob
。如果數(shù)據(jù)包含地址,它將是一個(gè)更復(fù)雜的對(duì)象,包含街道、城市、國(guó)家、郵政編碼等。
選擇多個(gè)聯(lián)系人
可以選擇多個(gè)聯(lián)系人。我們需要向navigator.contacts.select()
方法傳遞第二個(gè)參數(shù)來(lái)指示此選項(xiàng)。
const props = ["tel", "address", "icon", "name", "email"]; const options = { multiple: true }; const contacts = await navigator.contacts.select(props, options);
結(jié)果是一個(gè)聯(lián)系人數(shù)組,和上面的示例返回結(jié)果是一樣的。
總結(jié)
聯(lián)系信息是個(gè)人身份信息,我們必須以敏感數(shù)據(jù)所需的所有謹(jǐn)慎和安全性來(lái)處理它。
尊重人們的隱私。不要強(qiáng)迫他們分享他們不想分享的信息。
以安全的方式小心處理數(shù)據(jù)。如果您正在處理的數(shù)據(jù)是您自己的數(shù)據(jù),您會(huì)感到舒適嗎?
如果不需要,請(qǐng)不要存儲(chǔ)數(shù)據(jù)。讀它,用它,忘記它。不要存儲(chǔ)你不使用的數(shù)據(jù)。
只獲取您需要的數(shù)據(jù)。獲得建立信譽(yù)和信任所需的一切。
假設(shè)一個(gè)Web應(yīng)用程序試圖在選擇電話號(hào)碼時(shí)讀取地址、姓名或電子郵件。如果這種情況發(fā)生在我身上,我會(huì)拒絕授權(quán)并離開(kāi)這個(gè)網(wǎng)站。
作者:南城FE
鏈接:https://juejin.cn/post/7409147273736798260
來(lái)源:稀土掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。
該文章在 2024/9/2 10:47:46 編輯過(guò)