requestAutocomplete

收錢,不是我的時間

阿奇巴德 (Jake Archibald)
Jake Archibald

引言

我喜歡網路。總而言之,我覺得這是個好點子。因此,我接觸了許多網路與原生辯論會。其他人不必花費太多時間,討論可透過原生系統輕鬆付款。我平常的反應是把煙霧彈掉在房間裡大笑,因為沒有辦法獲勝。 在行動版網站中放棄購物車的機率高達 97%。想像一下在現實生活中想像一下,在超市有 97% 的消費者,購物車裡滿是想要的東西,在購物車中翻身然後出門。 如今,有些人只是在價格高低起伏,我們迫切需要課稅。 想想你在網路上 (尤其是行動裝置) 上享有愉快的付款體驗,這是應用程式商店,對吧?或者,至少已有付款資訊的類似已關閉系統。 這成為令人擔心的問題。根據規定,網站向使用者的付款供應商必須已擁有帳戶並登入,或是要找到需要使用者登入特定付款服務供應商的平台,例如應用程式商店 Xx,才會要求你只針對該平台編寫程式碼。如未完成上述任一動作,使用者就會離開螢幕或鍵盤,直到所有手指關掉或放棄。 我們必須修正這個問題。

requestAutocomplete

在這個 WebGL、WebRTC 和其他開頭為「Web」的酷炫網路 API 中,requestAutocomplete 的表現其實很好。但它是米黃色的超級英雄。這個小巧無聊的 API,能成為網路付款時間吸血鬼的核心。

網站並非仰賴特定付款服務供應商,而是會要求瀏覽器提供付款詳情,以便代表使用者儲存付款資料。 Chrome 版本的 requestAutocomplete() 也已和 Google 錢包整合,但僅適用於美國使用者前往測試網站試用

form.requestAutocomplete

表單元素具有一個新方法 requestAutocomplete,該方法會要求瀏覽器填入表單。瀏覽器會顯示對話方塊,要求使用者授予權限,並讓使用者選取想要提供的詳細資料。 您無法隨時呼叫這個方法,因為系統會在執行特定互動事件 (例如向上/向下、點擊、按鍵和觸控事件) 時呼叫這個方法。這屬於刻意設定的安全限制。

button.addEventListener('click', function(event) {
  form.requestAutocomplete();
  event.preventDefault();
});

// TODO: listen for autocomplete events on the form

在我們查看事件之前,必須確保瀏覽器能解讀您的表單欄位...

表單規定

以前網際網路都是黑白的,Internet Explorer 5 針對表單輸入元素採用新的屬性 autocomplete。可以將設定設為「關閉」,讓瀏覽器停止提供建議,這樣就大功告成了。這個 API 已經過擴充,可讓您在不修改「name」屬性的情況下指定欄位的預期內容,而 requestAutocomplete 就使用此 API 將表單欄位連結至使用者資料。

<input name="fullname" autocomplete="name">

根據規格,requestAutocomplete 並非付費專用,但 Chrome 目前的導入做法很可觀。未來瀏覽器或許能處理其他類型的資料,像是登入詳細資料和密碼產生器、護照資訊,甚至上傳虛擬圖像等。

目前 Chrome 的「requestAutocomplete」可辨識下列項目:

付款

  • 電子郵件
  • cc-name - 信用卡上的姓名
  • cc-number - 卡號
  • cc-exp-month - 信用卡到期月,以兩位數表示
  • cc-exp-year - 信用卡到期年份,以 4 位數表示
  • cc-csc - 3-4 位數卡片安全碼
<input type="email" autocomplete="email" name="email">
<input type="text" autocomplete="cc-name" name="card-name">
<input type="text" autocomplete="cc-number" name="card-num">
<input type="text" autocomplete="cc-exp-month" name="card-exp-month">
<input type="text" autocomplete="cc-exp-year" name="card-exp-year">
<input type="text" autocomplete="cc-csc" name="card-csc">

我使用的「名稱」屬性僅供參考,不需使用特定值。如果希望對沒有 requestAutocomplete 的使用者重複使用這份表單,建議您新增標籤、版面配置和基本 HTML5 驗證。

你也沒有隻能使用任何表單輸入類型,可以使用任何表單輸入類型。舉例來說,您可以在卡片到期欄位使用 <select>

控制台訊息詳細內容。
詳細的控制台訊息

地址

  • name - 全名。使用全名做為單一欄位遠比多個欄位好得多。許多欄位 (如名字和姓氏) 呈現西部偏誤,對其他文化來說可能沒有意義,而在單一欄位輸入資料也比較容易

  • tel - 包含國碼的完整電話號碼

    • tel-國家/地區代碼 - 例如 +44
    • tel-national - 其餘
  • 街道地址 - 完整地址 (以半形逗號分隔) 可細分為

    • 地址行 1
    • 地址行 2 - 可能空白
  • 縣市 - 縣市/鄉鎮

  • 區域 - 州/省代碼、縣市或行政區

  • 郵遞區號 - 郵遞區號、郵遞區號

  • country

上述項目應與: - 帳單 - 運費

<input type="text" autocomplete="billing name" required name="billing-name">
<input type="tel" autocomplete="billing tel" required name="billling-tel">
<input type="text" autocomplete="billing address-line1" required name="billing-address1">
<input type="text" autocomplete="billing address-line2" required name="billing-address2">
<input type="text" autocomplete="billing locality" required name="billing-locality">
<input type="text" autocomplete="billing region" required name="billing-region">
<input type="text" autocomplete="billing postal-code" required name="billing-postal-code">
<select autocomplete="billing country" required name="billing-country">
  <option value="US">United States</option>
  …
</select>

<input type="text" autocomplete="shipping name" name="shipping-name">
…

這裡再一次是範例名稱屬性,您可以使用想要的任何名稱。很明顯,不是所有表單都應要求運送地址。例如,請不要詢問我希望飯店客房送到哪裡,但他們目前的所在位置通常是賣點。 沒錯,因此我們提供了表單,並瞭解如何申請「autocompletion」。不過...

何時應呼叫 requestAutocomplete?

理想情況下,您不應載入結帳表單的頁面,而是顯示 requestAutocomplete 對話方塊。如果一切順利,使用者應該完全不會看到表單。

付款流程

常見的模式就是在購物車頁面中顯示「結帳」按鈕,點按即可前往付款詳情表單。在這種情況下,你想在購物車頁面中載入結帳表單,但對使用者隱藏表單,並在使用者點選「結帳」按鈕時呼叫 requestAutocomplete。請注意,你必須透過安全資料傳輸層 (SSL) 放送購物車頁面,才能避免收到 Skeletor 警告。首先,我們應該隱藏結帳按鈕,讓使用者在準備好之前無法點選結帳按鈕,但我們只想對使用 JavaScript 的使用者執行這項操作。因此,在頁面標頭中:

<script>document.documentElement.className += ' js';</script>

並在 CSS 中:

.js #checkout-button,
#checkout-form.for-autocomplete {
  display: none;
}

請務必在購物車頁面中加入結帳表單。這項工具可以前往任何地方,但上方的 CSS 可確保使用者不會看到這項資訊。

<form id="checkout-form" class="for-autocomplete" action="/checkout" method="post">
  …fields for payment, billing address &amp; shipping if relevant…
</form>

我們的 JavaScript 現在可以開始設定所有項目:

function enhanceForm() {
  var button = document.getElementById('checkout-button');
  var form = document.getElementById('checkout-form');

  // show the checkout button
  button.style.display = 'block';

  // exit early if there's no requestAutocomplete support
  if (!form.requestAutocomplete) {
    // be sure to show the checkout button so users can
    // access the basic payment form!
    return;
  }

  button.addEventListener('click', function(event) {
    form.requestAutocomplete();
    event.preventDefault();
  });

  // TODO: listen for autocomplete events on the form
}

有時您會在結帳表單和按鈕結束後呼叫購物車頁面上的 enhanceForm。支援 requestAutocomplete 的瀏覽器將享有最流暢的全新快速體驗,其他瀏覽器將改回使用一般的付款方式。 如果是獎勵積分,建議您透過 XHR 載入表單 HTML,做為 enhanceForm 的一部分。也就是說,您只能在支援 requestAutocomplete 的瀏覽器中載入表單,不必記得在呼叫 enhanceForm 的每個網頁上載入表單。這就是示範網站的運作方式。

你已經叫 requestAutocomplete,該怎麼做?

自動完成程序並非同步,requestAutocomplete 會立即傳回。為了瞭解具體情況,我們監聽幾個新事件:

form.addEventListener('autocomplete', function() {
  // hurrah! You got all the data you needed
});

form.addEventListener('autocompleteerror', function(event) {
  if (event.reason == 'invalid') {
    // the form was populated, but it failed html5 validation
    // eg, the data didn't match one of your pattern attributes
  }
  else if (event.reason == 'cancel') {
    // the user aborted the process
  }
  else if (event.reason == 'disabled') {
    // the browser supports requestAutocomplete, but it's not
    // available at this time. Eg, it wasn't called from an
    // interaction event or the page is insecure
  }
});

如果系統運作正常,您可以任意對資料進行操作,最簡單的做法是提交表單。伺服器會驗證資料,並向使用者顯示確認頁面,包括運費。如果資料無效,您可以顯示表單,並醒目顯示使用者需要修改的欄位。或者,您也可以直接提交表單,讓一般的伺服器端驗證接手。 如果使用者取消這項程序,您就不需要採取任何行動。如果這項功能已停用,請將使用者導向一般表單。因此在多數情況下,聽眾看起來會像這樣...

form.addEventListener('autocomplete', function() {
  form.submit();
});

form.addEventListener('autocompleteerror', function(event) {
  if (event.reason == 'invalid') {
    form.submit();
  }
  else if (event.reason != 'cancel') {
    window.location = '/checkout-page/';
  }
});

瀏覽器將我的資料儲存在何處?

規格並非決定資料儲存位置,因此可讓瀏覽器持續創新。 如果您已登入 Chrome,可以選擇將詳細資料儲存在 Google 錢包中,以便在其他已登入的裝置上存取。如果你在錢包中儲存詳細資料,requestAutocomplete 不會由卡片處理,因此安全性會有所提升。 如未登入 Chrome,或選擇不使用 Google 錢包,系統可能會選擇將詳細資料儲存在本機瀏覽器中,以便重複使用。 這個狀態是現行的,但未來 Chrome 和其他瀏覽器可能會採用其他付款服務供應商。

提供便利的付款體驗

當使用者每次購物時,都必須一再輸入付款資訊,這是真的讓人覺得很麻煩。網站儲存付款資料時,系統變得更加容易,我對於儲存卡片資料的網站數量不太清楚。這正是網路標準可以解決的理想問題。 requestAutocomplete 可讓您透過一鍵支付整個網路的費用,不必受制於特定服務或平台。此外,也不必受制於特定平台。

額外步驟:處理多頁表單

建議您呼叫 requestAutocomplete 一次並收集您需要的所有資料。如果您無法透過修改伺服器的方式一次接收所有資料,別擔心,只要從填妥的表單中擷取所需資料,然後按照最適合的方式提交即可。 您可以使用這個酷炫的簡易函式,擷取所有目前支援的資料做為簡單物件,而不必自行建立表單。取得資料後,你就可以轉換為伺服器所需的任何格式,然後發布至多個步驟。

checkoutButton.addEventListener('click', function() {
  requestUserData({
    billing: true,
    shipping: true
  }, function(response) {
    if (response.err == 'cancel') {
      // exit silently
      return;
    }
    if (response.err) {
      // fall back to normal form
      window.location.href = '/normal-checkout-form/';
      return;
    }

    // the rest is just made-up pseudo code as an example
    postToServer(data.shipping).then(function() {
      return postToServer(data.billing);
    }).then(function() {
      return postToServer(data.cc);
    }).catch(function() {
      // handle error
    });
  });
});