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 属性。

使用模板渲染响应

  • 将响应属性应用到 <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 作为 template 属性的值,在文档前面定义的引用模板中呈现响应,在具有 submit-successsubmit-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-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 属性在您的 form 上设置为 验证报告策略之一。
  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。如果这些不存在,用户将不会看到任何关于缺失错误状态的 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 autoexpand></textarea>

Polyfills

amp-form 扩展为某些浏览器中缺少或在下一版 CSS 中实现的行为和功能提供 polyfill。

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

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

用户交互伪类

:user-invalid:user-valid 伪类是 未来 CSS Selectors 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

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

有关如何使用它们的完整示例,请参阅此处

验证

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

需要更多帮助吗?

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

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

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

转到 GitHub