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
擴充功能也為瀏覽器中某些遺失的行為提供 Polyfill。
如果您要在表單中提交資料,您的伺服器端點必須實作 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>
輸入和欄位
允許
不允許
(未來可能會重新考慮放寬其中一些規則 - 如果您需要這些規則並提供使用案例,請告訴我們)。
如需有效輸入和欄位的詳細資訊,請參閱 AMP 驗證器規格中的 amp-form 規則。
成功和錯誤回應的呈現
您可以使用 amp-mustache 在表單中呈現成功或錯誤回應,或透過使用 amp-bind 的資料繫結和以下回應屬性來呈現成功回應
使用範本呈現回應
- 將回應屬性套用至
<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>
中的巢狀範本。在以下範例中,回應會在表單內的內嵌範本中呈現。
發佈者的 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
屬性擷取回應資料。 - 將 state 屬性新增至所需的元素,以繫結表單回應。
以下範例示範具有 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 表單為 <textarea>
元素提供 autoexpand
屬性。這可讓 textarea 展開和縮小以容納使用者的輸入列,最多可達欄位的最大尺寸。如果使用者手動調整欄位大小,則會移除自動展開行為。
<textarea autoexpand></textarea>
Polyfill
amp-form
擴充功能為某些瀏覽器中遺失或在下一個 CSS 版本中實作的行為和功能提供 Polyfill。
無效提交封鎖和驗證訊息泡泡
目前 (截至 2016 年 8 月) 使用 webkit 引擎的瀏覽器不支援無效的表單提交。這些瀏覽器包括所有平台上的 Safari,以及所有 iOS 瀏覽器。amp-form
擴充功能 Polyfill 此行為以封鎖任何無效的提交,並在無效輸入上顯示驗證訊息泡泡。
使用者互動虛擬類別
: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 方面引入複雜性。這可能會重新考慮並稍後推出 — 如果您認為有此需要,請提交問題。
屬性
action-xhr
指定伺服器端點以處理表單輸入,並透過 XMLHttpRequest (XHR) 提交表單。XHR 要求 (有時稱為 AJAX 要求) 是瀏覽器在不完整載入頁面或開啟新頁面的情況下發出要求的地方。瀏覽器會在背景中使用 Fetch API (如果可用),並在較舊的瀏覽器中回復為 XMLHttpRequest API 來傳送要求。
method=POST
需要此屬性,而 method=GET
則為選用屬性。
action-xhr
的值可以與 action
相同或不同的端點,並且具有與上述 action
相同的要求。
其他表單屬性
所有其他 表單屬性 都是選用的。
動作
amp-form
元素公開以下動作。
submit
可讓您在特定動作上觸發表單提交,例如,點擊連結,或 在輸入變更時提交表單。
clear
清空表單中每個輸入的值。這可讓使用者快速再次填寫表單。
活動
將 amp-form
事件與 on
屬性 搭配使用
以下範例同時監聽 submit-success
和 submit-error
事件,並根據事件顯示不同的燈箱
<form ... on="submit-success:success-lightbox;submit-error:error-lightbox" ... ></form>
submit
表單已提交,且在提交完成之前。
submit-success
表單提交已完成,且回應成功。
submit-error
表單提交已完成,且回應錯誤。
輸入事件
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>
請參閱 此處的完整範例。
樣式設定
類別和 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