AMP

amp-form

描述

允许您创建表单以在 AMP 文档中提交输入字段。

 

必需脚本

<script async custom-element="amp-form" src="https://cdn.ampproject.org/v0/amp-form-0.1.js"></script>

用法

amp-form 扩展允许您创建表单 (<form>) 以在 AMP 文档中提交输入字段。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>
在 Playground 中打开此代码段

输入和字段

允许

  • 其他与表单相关的元素,包括:<textarea><select><option><fieldset><label><input type=text><input type=submit> 等。
  • <input type=password><input type=file><form method=POST action-xhr> 中。
  • amp-selector

不允许

  • <input type=button><input type=image>
  • 输入上的大多数与表单相关的属性,包括:formformactionformtargetformmethod 等。

(将来可能会重新考虑放宽其中一些规则 - 如果您需要这些规则并提供用例,请告知我们)。

有关有效输入和字段的详细信息,请参阅 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-successsubmit-error 的响应提供有效的 JSON 对象。成功和错误响应都应具有 Content-Type: application/json 标头。

当将 <amp-form> 与另一个模板 AMP 组件(例如 <amp-list>)结合使用时,请注意模板可能不会在有效的 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 作为在具有 submit-successsubmit-error 属性的元素上设置的 template 属性的值,在文档前面定义的引用模板中呈现响应。

<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-Redirect-To 响应标头并指定重定向 URL,在成功提交表单后将用户重定向到新页面。重定向 URL 必须是 HTTPS URL,否则 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 By Example 中的表单提交与页面更新产品页面,它们演示了在表单提交后使用重定向。

自定义验证

amp-form 扩展允许你使用 custom-validation-reporting 属性以及以下报告策略之一来构建自定义验证 UI:show-first-on-submitshow-all-on-submitas-you-go

要在你的表单上指定自定义验证

  1. 将表单上的 custom-validation-reporting 属性设置为验证报告策略之一。
  2. 提供你自己的验证 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>
在 Playground 中打开此代码段

对于验证消息,如果你的元素内部没有文本内容,AMP 将使用浏览器的默认验证消息填充它。在上面的示例中,当 name5 输入为空且验证启动时(即,用户尝试提交表单),AMP 将使用浏览器的验证消息填充 <span visible-when-invalid="valueMissing" validation-for="name5"></span>,并向用户显示该 span

你必须为输入可能具有的每种无效状态提供你自己的验证 UI。如果这些 UI 不存在,用户将看不到任何缺失错误状态的 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-submitas-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 的下一个版本中实现的行为和功能提供 polyfill。

无效提交阻止和验证消息气泡

当前(截至 2016 年 8 月)使用基于 webkit 的引擎的浏览器不支持无效的表单提交。其中包括所有平台上的 Safari 和所有 iOS 浏览器。amp-form 扩展 polyfill 此行为以阻止任何无效提交,并在无效输入上显示验证消息气泡。

用户交互伪类

:user-invalid:user-valid 伪类是 未来 CSS 选择器 4 规范的一部分,引入这些伪类是为了允许更好地根据一些标准来设置无效/有效字段的样式。

: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 URL(绝对或相对),并且不能是指向 CDN 的链接。

  • 对于 method=GET:使用此属性或 action-xhr
  • 对于 method=POST:使用 action-xhr 属性。

targetaction 属性仅用于非 xhr GET 请求。AMP 运行时将使用 action-xhr 发出请求,并且将忽略 actiontarget。如果未提供 action-xhr,则 AMP 向 action 端点发出 GET 请求,并使用 target 打开一个新窗口(如果为 _blank)。在 amp-form 扩展加载失败的情况下,AMP 运行时也可能会退回到使用 actiontarget

action-xhr

指定一个服务器端点来处理表单输入并通过 XMLHttpRequest (XHR) 提交表单。XHR 请求(有时称为 AJAX 请求)是指浏览器在不完全加载页面或打开新页面的情况下发出请求。浏览器将使用 Fetch API 在后台发送请求(如果可用),并为较旧的浏览器回退到 XMLHttpRequest API

你的 XHR 端点必须实现 CORS 安全的要求。

此属性对于 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

从窗口 URL 的搜索字符串初始化表单字段,其中查询参数名称与字段名称匹配。当此属性存在时,<input><select><textarea> 字段可以选择性地进行初始化。

如果单个字段包含属性 data-allow-initialization,则表示该字段已选择加入。在页面加载时,如果 URL 包含与已选择加入的字段的 name 属性匹配的名称的查询参数,则该字段的值或选中状态将根据该查询参数的值进行更新。例如,如果使用 URL 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> 类型包括 checkboxcolordatedatetime-localemailhiddenmonthnumberradiorangesearchteltexttimeurlweek
  • 不支持利用变量替换的字段(具有属性 data-amp-replace 的字段)。
  • AMP 缓存提供的 AMP 页面不支持此功能。data-initialize-from-urldata-allow-initialization 属性不会导致 AMP 验证失败,但表单字段不会从 URL 初始化。

xssi-prefix

指定在解析从 action-xhr 端点获取的 JSON 之前,应去除前缀。如果响应中不存在前缀,则此属性将不起作用。这对于包含 安全前缀(例如 )]})以帮助防止跨站点脚本攻击的 API 很有用。

其他表单属性

所有其他 表单属性都是可选的。

custom-validation-reporting

这是一个可选属性,用于启用和选择自定义验证报告策略。有效值包括:show-first-on-submitshow-all-on-submitas-you-go

有关更多详细信息,请参阅自定义验证部分。

操作

amp-form 元素公开以下操作。

submit

允许您在特定操作上触发表单提交,例如,点击链接或在输入更改时提交表单

clear

清空表单中每个输入的值。这可以允许用户快速第二次填写表单。

活动

amp-form 事件与 on 属性一起使用

以下示例侦听 submit-successsubmit-error 事件,并根据事件显示不同的灯箱

<form
  ...
  on="submit-success:success-lightbox;submit-error:error-lightbox"
  ...
></form>

submit

表单已提交,并且在提交完成之前。

submit-success

表单提交已完成,并且响应成功。

submit-error

表单提交已完成,并且响应是错误。

verify

启动异步验证。

verify-error

异步验证已完成,并且响应是错误。

valid

表单的验证状态更改为“有效”(根据其报告策略)。

invalid

表单的验证状态更改为“无效”(根据其报告策略)。

输入事件

AMP 在子级 <input> 元素上公开 changeinput-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>
在 Playground 中打开此代码段

请在此处查看完整示例

分析

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-submitamp-form-submit-successamp-form-submit-error 事件触发时,它会生成以下包含表单中指定的值的变量

  • formId
  • formFields[comment]

样式

类和 CSS 钩子

amp-form 扩展为发布商提供了用于设置表单和输入样式的类和 CSS 钩子。

以下类可用于指示表单提交的状态

  • .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

发布商可以使用这些类来设置其输入和字段集的样式,以便对用户操作做出响应(例如,在用户模糊焦点后用红色边框突出显示无效输入)。

请参阅此处的完整示例,了解如何使用这些类。

验证

请参阅 AMP 验证器规范中的 amp-form 规则

需要更多帮助?

您已经阅读本文档十几次了,但它并没有真正涵盖您的所有问题?也许其他人也有同样的感觉:在 Stack Overflow 上联系他们。

转到 Stack Overflow
发现错误或缺少功能?

AMP 项目强烈鼓励您的参与和贡献!我们希望您能成为我们开源社区的持续参与者,但也欢迎您对您特别热衷的问题做出一次性贡献。

转到 GitHub