本文翻譯自 Read Phone Contacts with JavaScript,作者:Alvaro Montoro, 略有刪改。
作者注:本文中描述的技術和流程是實驗性的,只能在少數(shù)瀏覽器中工作。在撰寫本文時,聯(lián)系人選擇器API僅支持 Android Chrome(從版本80開始)和iOS Safari(從版本14.5開始)。如果要檢查是否可使用這個功能,可以訪問這個演示網(wǎng)站alvaromontoro.com/demos/contacts/
體驗。
在以前使用JavaScript從手機訪問聯(lián)系人數(shù)據(jù)是不可想象的?,F(xiàn)在有了聯(lián)系人選擇器API,我們可以使用JavaScript來實現(xiàn)這個功能。
此功能在需要聯(lián)系人信息(如電話號碼或VoIP)的應用程序,通過這個功能我們可以在社交平臺中發(fā)現(xiàn)通訊錄中的好友(前提需要社交平臺有對應的手機號碼字段),或者需要填寫聯(lián)系人表單信息時則無需切換應用程序即可獲取到相應的數(shù)據(jù)。
API和設備將限制可用的屬性。開發(fā)者可以選擇以下五個標準屬性:
以上返回的都是數(shù)組形式,因為聯(lián)系人可以有多個電話、電子郵件或多個地址。為了保持一致性,即使它是單個值,返回的數(shù)據(jù)始終是一個數(shù)組。
隱私和安全
存儲在手機上的聯(lián)系人信息可能包含敏感信息,我們必須小心處理。我們需要必須考慮到隱私和安全問題:
聯(lián)系人選擇器API代碼必須在頂級瀏覽上下文中運行。 它防止外部代碼,如廣告或第三方插件,讀取手機上的聯(lián)系人列表。
聯(lián)系人選擇器API代碼只能在用戶手勢后運行。 開發(fā)者不能完全自動化這個過程,用戶必須采取行為觸發(fā)后讀取聯(lián)系人。
用戶必須允許訪問聯(lián)系人列表。 這個是由手機限制而不是JavaScript強加的。用戶必須授予瀏覽器訪問聯(lián)系人的權限(如果它還沒有授權)。
當他們第一次使用使用聯(lián)系人選擇器API的網(wǎng)站時,他們可能會收到這樣的提示:
手機會在每次使用聯(lián)系人選擇器API代碼時顯示這個彈出窗口,直到用戶點擊“允許”。聯(lián)系人選擇器API在未允許之前不會運行。這個一次性的,授權之后不會再彈出。
API和代碼
聯(lián)系人選擇器API只定義了兩個方法:
getProperties()
:返回設備上可讀取的屬性列表。在定義中有五個值:"address
"(地址)、"email
"(電子郵件)、"icon
"(這可能不是聯(lián)系人圖片)、"name
"(姓名)、"tel
"(電話),但設備可能不允許訪問所有這些屬性。
select()
:打開聯(lián)系人彈出窗口,并在用戶完成操作后返回選擇。它接受兩個參數(shù):要讀取的屬性列表和一個可選的對象,包含選項。
兩種方法都返回Promise
,但考慮到它們觸發(fā)的操作會阻止應用程序的正常流程,我們在處理它們時應該使用async / await
。
如前面隱私和安全部分所述,在調(diào)用API之前需要用戶操作,因此如果沒有用戶交互,我們就無法觸發(fā)任何內(nèi)容,因此我們新增一個按鈕:
<button onclick="getContactData()">Show contact data</button>
主要的代碼將在getContactData()
函數(shù)中。但在此之前如果聯(lián)系人選擇器API不可用,顯示按鈕沒有意義,在默認情況下隱藏按鈕(添加hidden屬性),僅在API可用時才顯示它。通過 "contacts" in navigator
判斷當前瀏覽器環(huán)境是否支持該API:
if ("contacts" in navigator) {
document.querySelector("button").removeAttribute("hidden");
}
接下來是核心的按鈕邏輯:
async function getContactData() {
// 指定將讀取哪些聯(lián)系人值
const props = ["tel", "name", "email"];
try {
// 打開本地聯(lián)系人選擇器(在權限被授予后)
const contacts = await navigator.contacts.select(props);
// 這將在本地聯(lián)系人選擇器關閉后執(zhí)行
if (contacts.length) {
// 如果有數(shù)據(jù),顯示
alert("選中的數(shù)據(jù): " + JSON.stringify(contacts));
} else {
// 沒有表示沒有選擇
alert("沒有選擇任何內(nèi)容");
}
} catch (ex) {
// 如果發(fā)生錯誤,顯示錯誤信息
alert(ex.message)
}
}
一旦按鈕觸發(fā)了這個功能,如果瀏覽器有權限,聯(lián)系人選擇頁將會顯示出來,展示基本信息:閱讀數(shù)據(jù)的URL,它將返回什么數(shù)據(jù),以及要從中挑選的聯(lián)系人列表。
關閉彈窗后,contacts
變量將以JSON格式存儲數(shù)據(jù),作為一個數(shù)組,其中包含所請求信息的對象(如果聯(lián)系人卡片中不可用,則可能為空)。
這是選擇了聯(lián)系人后的結果示例:
[ { "address": [], "email": [ "alvarosemail@gmail.com" ], "icon": [], "name": [ "Alvaro Montoro" ], "tel": [ "555-555-5555", "555-123-4567" ] } ]
如果數(shù)據(jù)包含圖標,則它將是帶有圖像的blob
。如果數(shù)據(jù)包含地址,它將是一個更復雜的對象,包含街道、城市、國家、郵政編碼等。
選擇多個聯(lián)系人
可以選擇多個聯(lián)系人。我們需要向navigator.contacts.select()
方法傳遞第二個參數(shù)來指示此選項。
const props = ["tel", "address", "icon", "name", "email"]; const options = { multiple: true }; const contacts = await navigator.contacts.select(props, options);
結果是一個聯(lián)系人數(shù)組,和上面的示例返回結果是一樣的。
總結
聯(lián)系信息是個人身份信息,我們必須以敏感數(shù)據(jù)所需的所有謹慎和安全性來處理它。
尊重人們的隱私。不要強迫他們分享他們不想分享的信息。
以安全的方式小心處理數(shù)據(jù)。如果您正在處理的數(shù)據(jù)是您自己的數(shù)據(jù),您會感到舒適嗎?
如果不需要,請不要存儲數(shù)據(jù)。讀它,用它,忘記它。不要存儲你不使用的數(shù)據(jù)。
只獲取您需要的數(shù)據(jù)。獲得建立信譽和信任所需的一切。
假設一個Web應用程序試圖在選擇電話號碼時讀取地址、姓名或電子郵件。如果這種情況發(fā)生在我身上,我會拒絕授權并離開這個網(wǎng)站。
作者:南城FE
鏈接:https://juejin.cn/post/7409147273736798260
來源:稀土掘金
著作權歸作者所有。商業(yè)轉載請聯(lián)系作者獲得授權,非商業(yè)轉載請注明出處。
該文章在 2024/9/2 10:47:46 編輯過