amp-form
說明
讓您可以在 AMP 文件中建立表單,以提交輸入欄位。
必要指令碼
<script async custom-element="amp-form" src="https://cdn.ampproject.org/v0/amp-form-0.1.js"></script>
用法
amp-form
擴充功能可讓您在 AMP 文件中建立表單 (<form>
),以提交輸入欄位。amp-form
擴充功能也為瀏覽器中某些遺失的行為提供 polyfills。
如果您要在表單中提交資料,您的伺服器端點必須實作 CORS 安全性的要求。
在建立 <form>
之前,您必須加入 <amp-form>
擴充功能的必要指令碼,否則您的文件將會無效。如果您為了提交值以外的目的而使用 input
標記 (例如,不在 <form>
內的輸入),則不需要載入 amp-form
擴充功能。
<form method="post" action-xhr="https://example.com/subscribe" target="_top"> <fieldset> <label> <span>Name:</span> <input type="text" name="name" required> </label> <br> <label> <span>Email:</span> <input type="email" name="email" required> </label> <br> <input type="submit" value="Subscribe"> </fieldset> <div submit-success> <template type="amp-mustache"> Subscription successful! </template> </div> <div submit-error> <template type="amp-mustache"> Subscription failed! </template> </div> </form>
輸入和欄位
允許
- 其他表單相關元素,包括:
<textarea>
、<select>
、<option>
、<fieldset>
、<label>
、<input type=text>
、<input type=submit>
等等。 <form method=POST action-xhr>
內的<input type=password>
和<input type=file>
。amp-selector
不允許
<input type=button>
、<input type=image>
- 輸入中大多數的表單相關屬性,包括:
form
、formaction
、formtarget
、formmethod
和其他屬性。
(未來可能會重新考慮放寬其中一些規則 - 如果您需要這些規則並提供使用案例,請告訴我們)。
如需有效輸入和欄位的詳細資訊,請參閱 AMP 驗證器規格中的 amp-form 規則。
成功和錯誤回應呈現
您可以使用 amp-mustache 在表單中呈現成功或錯誤回應,或透過使用 amp-bind 和以下回應屬性進行資料繫結來呈現成功回應
回應屬性 | 說明 |
---|---|
submit-success |
如果回應成功 (亦即,狀態為 2XX ),可用於顯示成功訊息。 |
submit-error |
如果回應不成功 (亦即,狀態不是 2XX ),可用於顯示提交錯誤。 |
submitting |
可用於在表單提交時顯示訊息。此屬性的範本可以存取表單的輸入欄位,以用於任何顯示目的。請參閱下方的 完整表單範例,瞭解如何使用 submitting 屬性。 |
使用範本呈現回應
- 將回應屬性套用至
<form>
元素的任何子系。 - 在子元素中呈現回應,方法是在其中加入範本,透過
<template></template>
或<script type="text/plain"></script>
標記,或透過參照具有template="id_of_other_template"
屬性的範本。 - 為
submit-success
和submit-error
的回應提供有效的 JSON 物件。成功和錯誤回應都應具有Content-Type: application/json
標頭。
<amp-list>
) 使用 <amp-form>
時,請注意,範本可能無法在有效的 AMP 文件中巢狀結構化。在這種情況下,有效的解決方法是透過 template
屬性依 id
提供範本。進一步瞭解 <amp-mustache>
中的巢狀範本。在以下範例中,回應是在表單內的內嵌範本中呈現。
<form ...> <fieldset> <input type="text" name="firstName" /> ... </fieldset> <div submitting> <template type="amp-mustache"> Form submitting... Thank you for waiting {{name}}. </template> </div> <div submit-success> <template type="amp-mustache"> Success! Thanks {{name}} for subscribing! Please make sure to check your email {{email}} to confirm! After that we'll start sending you weekly articles on {{#interests}}<b>{{name}}</b> {{/interests}}. </template> </div> <div submit-error> <template type="amp-mustache"> Oops! {{name}}, {{message}}. </template> </div> </form>
發佈者的 action-xhr
端點傳回以下 JSON 回應
成功時
{ "name": "Jane Miller", "interests": [ {"name": "Basketball"}, {"name": "Swimming"}, {"name": "Reading"} ], "email": "email@example.com" }
發生錯誤時
{ "name": "Jane Miller", "message": "The email (email@example.com) you used is already subscribed." }
您可以透過使用範本的 ID 作為 template
屬性的值,在文件中稍早定義的參照範本中呈現回應,並在具有 submit-success
和 submit-error
屬性的元素上設定。
<template type="amp-mustache" id="submit_success_template"> Success! Thanks {{name}} for subscribing! Please make sure to check your email {{email}} to confirm! After that we'll start sending you weekly articles on {{#interests}}<b>{{name}}</b> {{/interests}}. </template> <template type="amp-mustache" id="submit_error_template"> Oops! {{name}}, {{message}}. </template> <form ...> <fieldset> ... </fieldset> <div submit-success template="submit_success_template"></div> <div submit-error template="submit_error_template"></div> </form>
請參閱此處的完整範例。
使用資料繫結呈現成功的回應
- 使用 on 屬性將表單 submit-success 屬性繫結至
AMP.setState()
。 - 使用
event
屬性擷取回應資料。 - 將狀態屬性新增至所需的元素,以繫結表單回應。
以下範例示範具有 amp-bind
的表單 submit-success
回應
<p [text]="'Thanks, ' + subscribe +'! You have successfully subscribed.'"> Subscribe to our newsletter </p> <form method="post" action-xhr="/components/amp-form/submit-form-input-text-xhr" target="_top" on="submit-success: AMP.setState({'subscribe': event.response.name})" > <div> <input type="text" name="name" placeholder="Name..." required /> <input type="email" name="email" placeholder="Email..." required /> </div> <input type="submit" value="Subscribe" /> </form>
當表單成功提交時,它會傳回類似以下的 JSON 回應
{ "name": "Jane Miller", "email": "email@example.com" }
然後 amp-bind
會更新 <p>
元素的文字,以符合 subscibe
狀態
... <p [text]="'Thanks, ' + subscribe +'! You have successfully subscribed.'"> Thanks Jane Miller! You have successfully subscribed. </p> ...
提交後重新導向
您可以透過設定 AMP-Redirect-To
回應標頭並指定重新導向網址,在表單成功提交後將使用者重新導向至新頁面。重新導向網址必須是 HTTPS 網址,否則 AMP 會擲回錯誤,且不會發生重新導向。HTTP 回應標頭是透過您的伺服器設定。
請務必更新您的 Access-Control-Expose-Headers
回應標頭,將 AMP-Redirect-To
加入允許標頭清單。進一步瞭解 AMP 中的 CORS 安全性 中的這些標頭。
範例回應標頭
AMP-Redirect-To: https://example.com/forms/thank-you Access-Control-Expose-Headers: AMP-Redirect-To
自訂驗證
amp-form
擴充功能可讓您透過使用 custom-validation-reporting
屬性以及以下其中一種回報策略:show-first-on-submit
、show-all-on-submit
或 as-you-go
,來建構您自己的自訂驗證 UI。
若要在表單上指定自訂驗證
- 將
form
上的custom-validation-reporting
屬性設定為 驗證回報策略之一。 - 提供您自己的驗證 UI,並以特殊屬性標記。AMP 將探索特殊屬性,並在正確的時間回報它們,具體取決於您指定的回報策略。
以下範例
<form method="post" action-xhr="https://example.com/subscribe" custom-validation-reporting="show-all-on-submit" target="_blank"> <fieldset> <label> <span>Name:</span> <input type="text" name="name" id="name5" required pattern="\w+\s\w+"> <span visible-when-invalid="valueMissing" validation-for="name5"></span> <span visible-when-invalid="patternMismatch" validation-for="name5"> Please enter your first and last name separated by a space (e.g. Jane Miller) </span> </label> <br> <label> <span>Email:</span> <input type="email" name="email" id="email5" required> <span visible-when-invalid="valueMissing" validation-for="email5"></span> <span visible-when-invalid="typeMismatch" validation-for="email5"></span> </label> <br> <input type="submit" value="Subscribe"> </fieldset> </form>
對於驗證訊息,如果您的元素內部沒有文字內容,AMP 將使用瀏覽器的預設驗證訊息填入。在以上範例中,當 name5
輸入為空且啟動驗證時 (亦即,使用者嘗試提交表單),AMP 將使用瀏覽器的驗證訊息填入 <span visible-when-invalid="valueMissing" validation-for="name5"></span>
,並向使用者顯示該 span
。
custom-validation-reporting
。有效性狀態可在 官方 W3C HTML 驗證回報文件中找到。回報策略
為 custom-validation-reporting
屬性指定以下其中一種回報選項
提交時顯示第一個
當預設驗證啟動時,show-first-on-submit
回報選項會模仿瀏覽器的預設行為。它會顯示找到的第一個驗證錯誤,並在此停止。
提交時顯示全部
show-all-on-submit
回報選項會在提交表單時,顯示所有無效輸入上的所有驗證錯誤。如果您想要顯示驗證摘要,這會很有用。
隨輸入隨顯示
as-you-go
回報選項可讓您的使用者在與輸入互動時看到驗證訊息。例如,如果使用者輸入無效的電子郵件地址,使用者會立即看到錯誤。一旦他們更正值,錯誤就會消失。
互動並提交
interact-and-submit
回報選項結合了 show-all-on-submit
和 as-you-go
的行為。個別欄位會在互動後立即顯示任何錯誤,並且在提交時,表單會顯示所有無效欄位上的錯誤。
驗證
HTML5 驗證僅根據頁面上可用的資訊提供意見回饋,例如值是否符合特定模式。透過 amp-form
驗證,您可以提供使用者 HTML5 驗證單獨無法提供的意見回饋。例如,表單可以使用驗證來檢查電子郵件地址是否已註冊。另一個使用案例是驗證城市欄位和郵遞區號欄位是否彼此相符。
以下範例
<h4>Verification example</h4> <form method="post" action-xhr="/form/verify-json/post" verify-xhr="/form/verify-json/post" target="_blank"> <fieldset> <label> <span>Email</span> <input type="text" name="email" required> </label> <label> <span>Zip Code</span> <input type="tel" name="zip" required pattern="[0-9]{5}(-[0-9]{4})?"> </label> <label> <span>City</span> <input type="text" name="city" required> </label> <label> <span>Document</span> <input type="file" name="document" no-verify> </label> <div class="spinner"></div> <input type="submit" value="Submit"> </fieldset> <div submit-success> <template type="amp-mustache"> <p>Congratulations! You are registered with {{email}}</p> </template> </div> <div submit-error> <template type="amp-mustache"> {{#verifyErrors}} <p>{{message}}</p> {{/verifyErrors}}{{^verifyErrors}} <p>Something went wrong. Try again later?</p> {{/verifyErrors}} </template> </div> </form>
表單會將 __amp_form_verify
欄位作為表單資料的一部分傳送,以提示伺服器要求是驗證要求,而不是正式提交。如果驗證和提交使用相同的端點,這有助於伺服器知道不要儲存驗證要求。
以下是驗證的錯誤回應應有的外觀
{ "verifyErrors": [ {"name": "email", "message": "That email is already taken."}, {"name": "zip", "message": "The city and zip do not match."} ] }
若要從 verify-xhr
要求中移除欄位,請將 no-verify
屬性新增至輸入元素。
如需更多範例,請參閱 examples/forms.amp.html。
變數替換
amp-form
擴充功能允許針對隱藏且具有 data-amp-replace
屬性的輸入進行 平台變數替換。在每次表單提交時,amp-form
會尋找表單內的所有 input[type=hidden][data-amp-replace]
,並將變數替換套用至其 value
屬性,並將其替換為替換結果。
您必須透過指定 data-amp-replace
中使用的變數的空格分隔字串,在每個輸入上提供您用於每個替換的變數 (請參閱以下範例)。AMP 將不會替換未明確指定的變數。
以下範例說明輸入在替換之前和之後的情況 (請注意,您需要使用變數替換的平台語法,而不是分析語法)
<!-- Initial Load --> <form ...> <input name="canonicalUrl" type="hidden" value="The canonical URL is: CANONICAL_URL - RANDOM - CANONICAL_HOSTNAME" data-amp-replace="CANONICAL_URL RANDOM" /> <input name="clientId" type="hidden" value="CLIENT_ID(myid)" data-amp-replace="CLIENT_ID" /> ... </form>
一旦使用者嘗試提交表單,AMP 將嘗試解析變數,並使用適當的替換更新所有欄位的 value
屬性。對於 XHR 提交,所有變數都可能被替換和解析。但是,在非 XHR GET 提交中,由於先前未解析,因此需要非同步解析的值可能無法使用。例如,如果先前未解析和快取 CLIENT_ID
,則它將無法解析。
<!-- User submits the form, variables values are resolved into fields' value --> <form ...> <input name="canonicalUrl" type="hidden" value="The canonical URL is: https://example.com/hello - 0.242513759125 - CANONICAL_HOSTNAME" data-amp-replace="CANONICAL_URL RANDOM" /> <input name="clientId" type="hidden" value="amp:asqar893yfaiufhbas9g879ab9cha0cja0sga87scgas9ocnas0ch" data-amp-replace="CLIENT_ID" /> ... </form>
請注意,上面的 CANONICAL_HOSTNAME
如何未被替換,因為它不在第一個欄位的 data-amp-replace
屬性中的允許清單中。
替換將在每次後續提交時發生。進一步瞭解 AMP 中的變數替換。
自動展開
AMP 表單為 <textarea>
元素提供 autoexpand
屬性。這可讓文字區域展開和收縮,以容納使用者的輸入列,直到欄位的最大大小為止。如果使用者手動調整欄位大小,則會移除自動展開行為。
<textarea autoexpand></textarea>
Polyfills
amp-form
擴充功能為某些瀏覽器中遺失或正在 CSS 下一個版本中實作的行為和功能提供 polyfills。
無效提交封鎖和驗證訊息泡泡
目前 (截至 2016 年 8 月) 使用 webkit 型引擎的瀏覽器不支援無效表單提交。這些包括所有平台上的 Safari 和所有 iOS 瀏覽器。amp-form
擴充功能 polyfills 此行為以封鎖任何無效提交,並在無效輸入上顯示驗證訊息泡泡。
使用者互動虛擬類別
:user-invalid
和 :user-valid
虛擬類別是 未來 CSS Selectors 4 規格的一部分,引入它們是為了允許更好的 Hook,以便根據一些條件設定無效/有效欄位的樣式。
:invalid
和 :user-invalid
之間的主要差異之一是它們何時套用至元素。在使用者與欄位進行重大互動後 (例如,使用者在欄位中輸入內容或從欄位模糊焦點),會套用 :user-invalid
類別。
amp-form
擴充功能提供 類別來 polyfill 這些虛擬類別。amp-form
擴充功能也會將這些類別傳播到上層 form
。但是,fieldset
元素只會始終設定為具有類別「user-valid」,以與瀏覽器行為保持一致。
<textarea>
驗證
規則運算式比對是大多數輸入元素 (<textarea>
除外) 原生支援的常見驗證功能。我們 polyfill 此功能,並支援 <textarea>
元素上的 pattern
屬性。
安全性考量
防止 XSRF 攻擊
除了遵循 AMP CORS 規格中的詳細資訊外,請特別注意 「處理狀態變更要求」 區段,以防止 XSRF 攻擊,其中攻擊者可以使用目前的使用者工作階段執行未經授權的命令,而使用者不知情。
一般而言,接受使用者輸入時,請記住以下幾點
- 狀態變更要求僅使用 POST。
- 僅針對導覽目的使用非 XHR GET (例如,搜尋)。
- 非 XHR GET 要求將不會收到準確的來源/標頭,而且後端將無法使用上述機制防止 XSRF 攻擊。
- 一般而言,僅針對導覽或資訊擷取使用 XHR/非 XHR GET 要求。
- AMP 文件中不允許非 XHR POST 要求。這是因為跨瀏覽器在這些要求上設定
Origin
標頭的不一致性,以及支援它會在防止 XSRF 攻擊方面引入的複雜性。稍後可能會重新考慮並引入 - 如果您認為需要此功能,請提交問題。
屬性
target
指出在提交表單後,要在何處顯示表單回應。值必須是 _blank
或 _top
。
action
指定伺服器端點以處理表單輸入。值必須是 https
網址 (絕對或相對),且不得為 CDN 的連結。
- 針對
method=GET
:使用此屬性或action-xhr
。 - 針對
method=POST
:使用action-xhr
屬性。
target
和 action
屬性僅用於非 xhr GET 要求。AMP 執行階段將使用 action-xhr
來發出要求,並忽略 action
和 target
。當未提供 action-xhr
時,AMP 會向 action
端點發出 GET 要求,並使用 target
開啟新視窗 (如果為 _blank
)。在 amp-form
擴充功能載入失敗的情況下,AMP 執行階段也可能會回復為使用 action
和 target
。
action-xhr
指定伺服器端點以處理表單輸入,並透過 XMLHttpRequest (XHR) 提交表單。XHR 要求 (有時稱為 AJAX 要求) 是指瀏覽器會在沒有完整載入頁面或開啟新頁面的情況下發出要求。瀏覽器將使用 Fetch API (如果可用) 在背景中傳送要求,並回復為適用於舊版瀏覽器的 XMLHttpRequest API。
此屬性是 method=POST
的必要屬性,而對於 method=GET
則是選用屬性。
action-xhr
的值可以與 action
相同或不同的端點,並且具有與上述 action
相同的要求。
若要瞭解在成功提交表單後重新導向使用者的相關資訊,請參閱下方的 提交後重新導向 區段。
enctype
enctype 屬性指定在透過 method=POST
提交將表單資料傳送至伺服器之前,應如何編碼表單資料。預設編碼設定為 multipart/form-data
。目前支援此編碼類型和 application/x-www-form-urlencoded
編碼類型。
enctype 值摘要
application/x-www-form-urlencoded
- 將編碼類型設定為application/x-www-form-urlencoded
。multipart/form-data
- 將編碼類型設定為multipart/form-data
。任何值
或未指定 - 將enctype
屬性設定為未在上方指定的值,或完全未設定屬性,將導致預設編碼類型為multipart/form-data
。
data-initialize-from-url
從視窗網址的搜尋字串初始化表單欄位,其中查詢參數名稱符合欄位的名稱。當此屬性存在時,可以選擇性地初始化 <input>
、<select>
和 <textarea>
欄位。
如果個別欄位包含屬性 data-allow-initialization
,則會選擇加入。在頁面載入時,如果網址包含查詢參數,且名稱符合選擇加入欄位的 name
屬性,則該欄位的值或勾選狀態將根據該查詢參數的值更新。例如,如果使用網址 https://example.com/search?q=my+search
瀏覽 AMP 頁面,<input type="search" name="q" data-allow-initialization>
會顯示「my search」。
範例
<form data-initialize-from-url method="get" action="https://example.com/search" target="_top"> <label>Search: <input type="search" name="q" data-allow-initialization></label> </form> <!-- display search results using amp-list -->
限制
- 支援的
<input>
類型包括checkbox
、color
、date
、datetime-local
、email
、hidden
、month
、number
、radio
、range
、search
、tel
、text
、time
、url
和week
。 - 不支援利用 變數替換 的欄位 (具有屬性
data-amp-replace
的欄位)。 - AMP 快取不支援在 AMP 快取傳遞的 AMP 頁面上使用此功能。
data-initialize-from-url
和data-allow-initialization
屬性不會導致 AMP 驗證失敗,但表單欄位不會從網址初始化。
xssi-prefix
指定在剖析從 action-xhr
端點擷取的 json 之前,應剝離前置字串。如果回應中不存在前置字串,則此屬性將不會產生任何作用。這對於包含 安全性前置字串 (例如 )]}
) 的 API 可能很有用,以協助防止跨網站指令碼攻擊。
其他表單屬性
所有其他 表單屬性都是選用的。
custom-validation-reporting
這是一個選用屬性,可啟用並選取自訂驗證回報策略。有效值為以下其中之一:show-first-on-submit
、show-all-on-submit
或 as-you-go
。
請參閱 自訂驗證 區段以瞭解更多詳細資訊。
動作
amp-form
元素公開以下動作。
submit
可讓您在特定動作上觸發表單提交,例如,輕觸連結,或 在輸入變更時提交表單。
clear
清空表單中每個輸入的值。這可讓使用者快速再次填寫表單。
活動
搭配 on
屬性使用 amp-form
事件
以下範例同時監聽 submit-success
和 submit-error
事件,並根據事件顯示不同的燈箱
<form ... on="submit-success:success-lightbox;submit-error:error-lightbox" ... ></form>
submit
表單已提交,並且在提交完成之前。
submit-success
表單提交完成,且回應成功。
submit-error
表單提交完成,且回應發生錯誤。
verify
非同步驗證已啟動。
verify-error
非同步驗證完成,且回應發生錯誤。
valid
表單的驗證狀態變更為「有效」(根據其回報策略)。
invalid
表單的驗證狀態變更為「無效」(根據其回報策略)。
輸入事件
AMP 在子系 <input>
元素上公開 change
和 input-debounced
事件。這可讓您使用 on
屬性,在輸入值變更時,對任何元素執行動作。
例如,常見的使用案例是在輸入變更時提交表單 (選取單選按鈕以回答投票、從 select
輸入中選擇語言以翻譯頁面等)。
<form id="myform" method="post" action-xhr="https://example.com/myform" target="_blank"> <fieldset> <label> <input name="answer1" value="Value 1" type="radio" on="change:myform.submit">Value 1 </label> <label> <input name="answer1" value="Value 2" type="radio" on="change:myform.submit">Value 2 </label> </fieldset> </form>
請參閱此處的完整範例。
分析
amp-form
擴充功能觸發以下事件,您可以在 amp-analytics 設定中追蹤這些事件
事件 | 觸發時機 |
---|---|
amp-form-submit |
已啟動表單要求。 |
amp-form-submit-success |
已收到成功回應 (亦即,當回應的狀態為 2XX 時)。 |
amp-form-submit-error |
已收到不成功的回應 (亦即,當回應的狀態不是 2XX 時)。 |
您可以設定您的分析,以傳送這些事件,如以下範例所示
<amp-analytics> <script type="application/json"> { "requests": { "event": "https://www.example.com/analytics/event?eid=${eventId}", "searchEvent": "https://www.example.com/analytics/search?formId=${formId}&query=${formFields[query]}" }, "triggers": { "formSubmit": { "on": "amp-form-submit", "request": "searchEvent" }, "formSubmitSuccess": { "on": "amp-form-submit-success", "request": "event", "vars": { "eventId": "form-submit-success" } }, "formSubmitError": { "on": "amp-form-submit-error", "request": "event", "vars": { "eventId": "form-submit-error" } } } } </script> </amp-analytics>
所有三個事件都會產生一組變數,這些變數對應於特定表單和表單中的欄位。這些變數可用於分析。
例如,以下表單有一個欄位
<form action-xhr="/comment" method="POST" id="submit_form"> <input type="text" name="comment" /> <input type="submit" value="Comment" /> </form>
當 amp-form-submit
、amp-form-submit-success
或 amp-form-submit-error
事件觸發時,它會產生以下變數,其中包含表單中指定的值
formId
formFields[comment]
樣式設定
類別和 CSS Hook
amp-form
擴充功能提供類別和 CSS Hook,供發佈者設定其表單和輸入的樣式。
以下類別可用於指出表單提交的狀態
.amp-form-initial
.amp-form-verify
.amp-form-verify-error
.amp-form-submitting
.amp-form-submit-success
.amp-form-submit-error
以下類別是 使用者互動虛擬類別的 polyfill
.user-valid
.user-invalid
發佈者可以使用這些類別來設定其輸入和 fieldset 的樣式,使其能夠回應使用者動作 (例如,在使用者從無效輸入模糊焦點後,以紅色邊框醒目提示無效輸入)。
請參閱 此處的完整範例,瞭解如何使用這些類別。
驗證
請參閱 AMP 驗證器規格中的 amp-form 規則。
您已閱讀本文檔十幾次,但它並沒有真正涵蓋您的所有問題?可能其他人也有相同的感受:在 Stack Overflow 上與他們聯絡。
前往 Stack Overflow 發現錯誤或缺少功能?AMP 專案強烈鼓勵您的參與和貢獻!我們希望您能成為我們開放原始碼社群的持續參與者,但我們也歡迎針對您特別感興趣的問題提供一次性貢獻。
前往 GitHub