AMP

重要提示:此文档不适用于您当前选择的格式 故事

amp-access

描述

提供 AMP 付费墙和订阅支持。

 

必需的脚本

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

AMP Access 或“AMP 付费墙和订阅支持”使发布商可以根据阅读者的订阅状态、浏览次数和其他因素来控制阅读者可以访问哪些内容以及有哪些限制。

与 amp-subscriptions 的关系

amp-subscriptions 扩展提供了类似于 amp-access 的功能。但是,它支持更专业的访问付费墙协议。一些值得注意的差异是

  1. amp-subscriptions 授权响应类似于 amp-access 授权,但它是严格定义和标准化的。
  2. amp-subscriptions 扩展允许为页面配置多个服务以参与访问/付费墙决策。它们会并发执行,并根据哪个服务返回肯定响应来确定优先级。
  3. 允许 AMP 查看器根据与发布商的独立协议提供 amp-subscriptions 签名授权响应,作为访问的证明。
  4. amp-subscriptions 中,内容标记是标准化的,允许应用和爬虫程序轻松检测高级内容部分。

由于标记的标准化、多提供商支持和改进的查看器支持,建议新的发布商和付费墙提供商实现使用 amp-subscriptions

解决方案

建议的解决方案使发布商可以控制以下决策和流程

  • 创建和维护用户
  • 控制计量(允许一定数量的免费浏览)
  • 负责登录流程
  • 负责验证用户身份
  • 负责访问规则和授权
  • 灵活地按文档设置访问参数

该解决方案包括以下组件

  1. AMP 阅读器 ID:由 AMP 生态系统提供,这是 AMP 查看的阅读者的唯一标识符。
  2. 访问内容标记:由发布商编写,定义文档的哪些部分在哪些情况下可见。
  3. 授权端点:由发布商提供,返回解释阅读者可以消费文档的哪一部分的响应。
  4. 回传端点:由发布商提供,用于发送文档的“浏览”展示。
  5. 登录链接和登录页面:允许发布商验证阅读者身份并将其身份与 AMP 阅读器 ID 关联。

Google AMP 缓存将文档返回给阅读者,某些部分使用访问内容标记进行遮蔽。AMP 运行时调用授权端点,并使用响应来隐藏或显示访问内容标记定义的不同的部分。在向阅读者显示文档后,AMP 运行时调用回传端点,发布商可以使用该端点来更新倒计时计数器(已使用的免费浏览次数)。

该解决方案还允许发布商在 AMP 文档中放置一个登录链接,该链接会启动登录/订阅页面,发布商可以在该页面验证阅读者的身份,并将阅读者在其系统中的身份与 AMP 阅读器 ID 相关联。

在其基本形式中,此解决方案会将完整的(尽管是遮蔽的)文档发送给阅读者,并且仅根据授权响应显示/隐藏受限部分。但是,该解决方案还提供了“服务器”选项,其中受限部分可以从初始文档传递中排除,并且仅在确认授权后下载。

支持 AMP Access 要求发布商实现上述组件。访问内容标记和授权端点是必需的。回传端点和登录页面是可选的。

AMP 阅读器 ID

为了帮助访问服务和用例,AMP Access 引入了 阅读器 ID 的概念。

阅读器 ID 是由 AMP 生态系统创建的匿名唯一 ID。对于每个阅读者/发布商对来说,它是唯一的 - 阅读者对两个不同的发布商的标识是不同的。这是一个不可逆的 ID。阅读器 ID 包含在所有 AMP/发布商通信中,并具有非常高的熵。发布商可以使用阅读器 ID 来识别阅读者并将其映射到他们自己的身份系统。

阅读器 ID 在用户设备上构建,旨在长期存在。但是,它遵循正常的浏览器存储规则,包括隐身窗口的规则。阅读器 ID 的预期生命周期是两次使用之间 1 年,或者直到用户清除他们的 Cookie。阅读器 ID 当前不在设备之间共享。

阅读器 ID 的构建方式类似于 此处描述的用于构建 ExternalCID 的机制。阅读器 ID 的示例是 amp-OFsqR4pPKynymPyMmplPNMvxSTsNQob3TnK-oE3nwVT0clORaZ1rkeEz8xej-vV6

AMP Access 和 Cookie

发布商可以使用自己的身份验证 Cookie,也可以依赖阅读器 ID,或者两者结合使用。

访问内容标记

访问内容标记根据从授权端点返回的授权响应来确定哪些部分是可见的或隐藏的。它是通过特殊的标记属性描述的。

授权端点

授权是由发布商提供的端点,由 AMP 运行时或 Google AMP 缓存调用。它是经过身份验证的 CORS GET 端点。此端点返回访问参数,这些参数可以被内容标记用来隐藏或显示文档的不同部分。

回传端点

回传是由发布商提供的端点,由 AMP 运行时或 Google AMP 缓存调用。它是经过身份验证的 CORS POST 端点。当阅读者开始查看文档时,AMP 运行时会自动调用此端点。在阅读者成功完成登录流程后,也会调用此端点。回传的主要目标之一是让发布商更新计量信息。

回传是可选的。可以通过将 noPingback 配置属性设置为 true 来禁用它。

登录页面由发布商实现并提供服务,并由 AMP 运行时调用。它通常显示为浏览器对话框。

当阅读者点击可以由发布商放置在文档中任何位置的登录链接时,会触发登录页面。

规范 v0.1

配置

所有端点都在 AMP 文档中配置为文档 HEAD 中的 JSON 对象

<script id="amp-access" type="application/json">
  {
    "property": value,
    ...
  }
</script>

在此配置中定义了以下属性

属性 描述
authorization <URL> 授权端点的 HTTPS URL。
pingback <URL> 回传端点的 HTTPS URL。
noPingback true/false 为 true 时,禁用回传。
login <URL> 或
<Map[string, URL]>
登录页面的 HTTPS URL 或不同类型的登录页面的 URL 集。
authorizationFallbackResponse <object> 如果授权失败,则代替授权响应使用的 JSON 对象。
authorizationTimeout <number> 授权请求被视为失败后的超时时间(以毫秒为单位)。默认值为 3000。仅在开发环境中允许大于 3000 的值。
type “client” 或 “server” 默认值为“client”。“server”选项正在设计讨论中,当准备就绪时,这些文档将更新。
namespace 字符串 默认值为空。如果指定了多个访问提供商,则需要命名空间。

<URL> 值指定带有替换变量的 HTTPS URL。替换变量将在下面的 访问 URL 变量部分中更详细地介绍。

以下是 AMP Access 配置的示例

<script id="amp-access" type="application/json">
  {
    "authorization": "https://pub.com/amp-access?rid=READER_ID&url=SOURCE_URL",
    "pingback": "https://pub.com/amp-ping?rid=READER_ID&url=SOURCE_URL",
    "login": "https://pub.com/amp-login?rid=READER_ID&url=SOURCE_URL",
    "authorizationFallbackResponse": {"error": true}
  }
</script>

多个访问提供商

可以使用数组而不是单个对象并为每个条目提供 namespace 来指定多个访问提供商。

<script id="amp-access" type="application/json">
  [
    {
      "property": value,
      ...
      "namespace": value
    },
    ...
  ]
</script>

访问 URL 变量

在配置各种端点的 URL 时,发布商可以使用替换变量。这些变量的完整列表在 AMP Var 规范中定义。此外,此规范添加了一些特定于访问的变量,例如 READER_IDAUTHDATA。下表描述了一些最相关的变量

变量 描述
READER_ID AMP 阅读器 ID。
AUTHDATA(field) 授权响应中字段的值。
RETURN_URL 由 AMP 运行时指定的返回 URL 的占位符,以便登录对话框返回。
SOURCE_URL 此 AMP 文档的源 URL。如果文档从 CDN 提供,则 AMPDOC_URL 将是 CDN URL,而 SOURCE_URL 将是原始源 URL。
AMPDOC_URL 此 AMP 文档的 URL。
CANONICAL_URL 此 AMP 文档的规范 URL。
DOCUMENT_REFERRER 引用 URL。
VIEWER AMP 查看器的 URL。
RANDOM 一个随机数。有助于避免浏览器缓存。

以下是使用阅读器 ID、规范 URL、引用信息和随机缓存克星扩展的 URL 示例

https://pub.com/access?
   rid=READER_ID
  &url=CANONICAL_URL
  &ref=DOCUMENT_REFERRER
  &_=RANDOM

AUTHDATA 变量可用于回传和登录网址。它允许将授权响应中的任何字段作为 URL 参数传递。例如,AUTHDATA(isSubscriber)。也允许嵌套表达式,例如 AUTHDATA(other.isSubscriber)。如果使用命名空间,则可以将命名空间添加到字段前,例如 AUTHDATA(anamespace.afield)

访问内容标记

访问内容标记描述了哪些部分是可见的或隐藏的。它由两个 AMP 属性组成:amp-accessamp-access-hide,它们可以放置在任何 HTML 元素上。

amp-access 属性提供一个表达式,该表达式基于授权端点返回的授权响应产生 true 或 false。结果值指示元素及其内容是否可见。

amp-access 值是一个在类似 SQL 的语言中定义的布尔表达式。其语法在附录 A中定义。定义如下:

<div amp-access="expression">...</div>

属性和值引用由授权端点返回的授权响应的属性和值。这提供了一个灵活的系统来支持不同的访问场景。如果使用命名空间,只需将命名空间添加到属性名称前,例如 anamespace.aproperty

amp-access-hide 属性可用于在收到授权响应之前乐观地隐藏元素,然后根据响应显示它。它提供了“默认不可见”的语义。授权稍后返回的授权响应可能会撤销此默认设置,并使该部分可见。当省略 amp-access-hide 属性时,默认情况下将显示/包含该部分。amp-access-hide 属性只能与 amp-access 属性一起使用。

<div amp-access="expression" amp-access-hide>...</div>

如果授权请求失败,则不会评估 amp-access 表达式,并且某个部分是可见还是隐藏由文档最初提供的 amp-access-hide 属性的存在来决定。

我们可以根据需要扩展 amp-access-* 属性集,以支持不同的混淆和渲染需求。

如果授权请求失败,并且文档中未指定 "authorizationFallbackResponse" 响应,则不会评估 amp-access 表达式,并且某个部分是可见还是隐藏将由文档最初提供的 amp-access-hide 属性的存在来决定。

这是一个示例,根据订阅状态显示登录链接或完整内容

<header>
  Title of the document
</header>

<div>
  First snippet in the document.
</div>

<div amp-access="NOT subscriber" amp-access-hide>
  <a on="tap:amp-access.login">Become a subscriber now!</a>
</div>

<div amp-access="subscriber">
  Full content.
</div>

这里

  • subscriber 是由授权端点返回的授权响应中的布尔字段。此部分默认隐藏,这是可选的。
  • 此示例选择乐观地显示完整内容。

这是另一个示例,向读者显示有关计量状态的免责声明

<section amp-access="views <= maxViews">
  <template amp-access-template type="amp-mustache">
    You are reading article {{views}} out of {{maxViews}}.
  </template>
</section>

这是另一个示例,向高级订阅者显示其他内容

<section amp-access="subscriptonType = 'premium'">
  Shhh… No one but you can read this content.
</section>

授权端点

授权通过AMP 访问配置部分中的 authorization 属性进行配置。它是一个带有凭据的 CORS GET 端点。有关此请求应如何保护,请参见CORS 源安全

授权可以采用访问 URL 变量部分中定义的任何参数。例如,它可以传递 AMP 阅读器 ID 和文档 URL。除了 URL 参数之外,发布者还可以使用通过 HTTP 协议自然传递的任何信息,例如阅读器的 IP 地址。必须包含 READER_ID

此端点生成授权响应,该响应可用于内容标记表达式中以显示/隐藏内容的不同部分。

请求格式为

https://publisher.com/amp-access.json?
   rid=READER_ID
  &url=SOURCE_URL

响应是一个自由形式的 JSON 对象:它可以包含任何属性和值,但有一些限制。限制如下:

  • 属性名称必须符合 amp-access 表达式语法定义的限制(请参阅附录 A)。这主要意味着属性名称不能包含空格、破折号和其他不符合 "amp-access" 规范的字符。
  • 属性值只能是以下类型之一:字符串、数字、布尔值。
  • 值也可以嵌套为具有相同类型值(字符串、数字、布尔值)的对象。
  • 序列化授权响应的总大小不能超过 500 字节。
  • 请确保响应不包含任何个人身份信息 (PII) 或个人数据。

以下是授权端点可能返回的属性的一些想法

  • 计量信息:允许的最大浏览次数和当前的浏览次数。
  • 读者是否已登录或是否为订阅者。
  • 更详细的订阅类型:基本版、高级版
  • 地理位置:国家、地区、自定义发布区域

以下示例是在读者不是订阅者且每月计量 10 篇文章并且已经浏览过 6 篇文章时的响应

{
  "maxViews": 10,
  "currentViews": 6,
  "subscriber": false
}

以下示例是在读者已登录并具有高级订阅类型时的响应

{
  "loggedIn": true,
  "subscriptionType": "premium"
}

此 RPC 可能会在预渲染阶段调用,因此不应将其用于计量倒计时,因为读者可能永远看不到该文档。

另一个重要的考虑因素是,在某些情况下,AMP 运行时可能需要每个文档展示调用授权端点多次。当 AMP 运行时认为读者的访问参数已发生显著变化时,就会发生这种情况,例如在成功完成登录流程之后。

授权响应可被 AMP 运行时和扩展用于三个不同的目的

  1. 评估 amp-access 表达式时。
  2. 评估诸如 amp-mustache 之类的 <template> 模板时。
  3. 在使用 AUTHDATA(field) 时向回传和登录 URL 提供其他变量时。

AMP 运行时以带有凭据的 CORS 端点的形式调用授权端点。因此,它必须实现 CORS 协议。它应该使用 CORS 源和源原点来限制对此服务的访问,如CORS 源安全中所述。此端点可能会出于自身需要使用发布者 Cookie。例如,它可以关联阅读器 ID 和发布者自己的用户身份之间的绑定。AMP 本身不需要了解这一点(并且最好不要了解)。有关更多详细信息,请参阅AMP 阅读器 IDAMP 访问和 Cookie 文档。

AMP 运行时(或者更确切地说是浏览器)在调用授权端点时会观察缓存响应标头。因此可以重用缓存的响应。这可能是可取的,也可能不是可取的。如果不是可取的,发布者可以使用适当的缓存控制标头和/或端点 URL 的 RANDOM 变量替换。

如果授权请求失败,则 AMP 运行时将回退到 "authorizationFallbackResponse",如果该响应在配置中指定。在这种情况下,授权流程将正常进行,使用 "authorizationFallbackResponse" 属性的值来代替授权响应。如果未指定 "authorizationFallbackResponse",则授权流程将失败,在这种情况下,将不会评估 amp-access 表达式,并且某个部分是可见还是隐藏将由文档最初提供的 amp-access-hide 属性的存在来决定。

授权请求在 3 秒后自动超时,并假定为失败。

AMP 运行时在授权流程期间使用以下 CSS 类

  1. 当授权流程开始时,在文档根目录上设置 amp-access-loading CSS 类,并在完成或失败时删除它。
  2. 当授权流程失败时,在文档根目录上设置 amp-access-error CSS 类。

服务器 选项中,对授权端点的调用由 Google AMP 缓存作为简单的 HTTPS 端点发出。这意味着在这种情况下无法传递发布者的 Cookie。

回传端点

回传通过AMP 访问配置部分中的 pingback 属性进行配置。它是一个带有凭据的 CORS POST 端点。有关此请求应如何保护,请参见CORS 源安全

回传 URL 是可选的。可以使用 "noPingback": true 禁用它。

回传 URL 可以采用访问 URL 变量部分中定义的任何参数。例如,它可以传递 AMP 阅读器 ID 和文档 URL。必须包含 READER_ID

回传不产生响应 - AMP 运行时会忽略任何响应。

当读者开始查看文档并在读者成功完成登录流程后,将调用回传端点。

发布者可以选择使用回传

  • 来计算页面免费浏览次数的倒计时
  • 将 AMP 阅读器 ID 映射到发布者的身份,因为作为带有凭据的 CORS 端点,回传可能包含发布者 Cookie

请求格式为

https://publisher.com/amp-pingback?
   rid=READER_ID
  &url=SOURCE_URL

登录页面

登录页面的 URL 通过AMP 访问配置部分中的 login 属性进行配置。

配置可以指定单个登录 URL,也可以指定按登录类型键入的登录 URL 映射。单个登录 URL 的示例

{
  "login": "https://publisher.com/amp-login.html?rid={READER_ID}"
}

多个登录 URL 的示例

{
  "login": {
    "signin": "https://publisher.com/signin.html?rid={READER_ID}",
    "signup": "https://publisher.com/signup.html?rid={READER_ID}"
  }
}

URL 可以采用访问 URL 变量部分中定义的任何参数。例如,它可以传递 AMP 阅读器 ID 和文档 URL。RETURN_URL 查询替换可用于指定返回 URL 的查询参数,例如 ?ret=RETURN_URL。返回 URL 是必需的,如果未指定 RETURN_URL 替换,则将使用默认查询参数名称 “return” 自动注入它。

登录页面只是一个普通的网页,没有特殊约束,除了它应该可以很好地作为浏览器对话框运行。有关更多详细信息,请参阅登录流程部分。

请求格式为

https://publisher.com/amp-login.html?
   rid=READER_ID
  &url=SOURCE_URL
  &return=RETURN_URL

请注意,如果未指定 RETURN_URL 替换,则 AMP 运行时会自动添加 "return" URL 参数。登录页面完成其工作后,必须使用以下格式重定向回指定的 “返回 URL”

RETURN_URL#success=true|false

请注意使用 URL 哈希参数 "success"。该值是 "true" 或 "false",具体取决于登录是成功还是放弃。理想情况下,登录页面在可能的情况下会在成功或失败的情况下发送信号。

如果返回 success=true 信号,则 AMP 运行时将重复调用授权和回传端点以更新文档状态并报告具有新访问配置文件的 “查看”。

发布者可以选择将登录链接放置在文档内容的任何位置。

一个或多个登录 URL 通过AMP 访问配置部分中的 "login" 属性进行配置。

登录链接可以在允许 "on" 属性的任何 HTML 元素上声明。通常,这将是锚元素或按钮元素。当配置单个登录 URL 时,格式为

<a on="tap:amp-access.login">Login or subscribe</a>

当配置多个登录 URL 时,格式为 tap:amp-access.login-{type}。例如

<a on="tap:amp-access.login-signup">Subscribe</a>

当使用命名空间时,格式为 tap:amp-access.login-{namespace}tap:amp-access.login-{namespace}-{type}

AMP 不区分登录和订阅。这种区分可以通过发布商使用多个登录 URL/链接或在发布商端进行配置。

amp-analytics 集成

amp-analytics 的集成在 amp-access-analytics.md 中有文档记录。

CORS 来源安全

授权和回传端点是 CORS 端点,它们必须实现 AMP CORS 安全规范 中描述的安全协议。

计量

计量是一种系统,在该系统中,读者在一段时间内可以免费查看几个文档的优质内容。一旦达到某个配额,付费墙就会启动,并且读者会看到带有追加销售信息和注册/登录链接的部分内容。例如,计量可以定义为“读者每月可以免费阅读 10 篇文章”。

AMP Access 提供以下功能来实现计量访问

  1. 应该使用 READER_ID 来存储计量信息。由于发布商不能依赖于始终能够在第三方上下文中设置 cookie,因此此数据应存储在服务器端。
  2. “阅读计数”只能在回传端点中更新。
  3. 只有唯一的文档才能计入配额。也就是说,刷新同一文档十次算作一次查看。为此,授权和回传端点可以注入 SOURCE_URL 或类似的 URL 变量。请参阅 访问 URL 变量

首次点击免费

Google 的首次点击免费 (FCF) 政策在此处进行了描述,最新更新在此处进行了更详细的描述。

要实现 FCF,发布商必须 (1) 能够确定每次查看的引荐服务,以及 (2) 能够计算每个读者每天的查看次数。

AMP Access 规范涵盖了这两个步骤。可以使用 访问 URL 变量中描述的 DOCUMENT_REFERRER URL 替换将引荐来源注入到授权和回传 URL 中。可以使用服务器端的回传端点来完成查看计数。这与 计量 中描述的计量实现非常相似。

登录流程

AMP 将登录对话框作为第一方窗口、弹出窗口或选项卡启动。在可能的情况下,AMP 查看器应尝试在浏览器上下文中启动登录对话框,以便它可以利用顶层浏览器 API。

当读者激活登录链接时,AMP 运行时会启动登录流程,并且,描述性地,它遵循以下步骤

  1. AMP 运行时或查看器会为指定的登录 URL 打开登录对话框(第一方窗口)。该 URL 包含一个额外的“返回 URL”URL 查询参数 (&return=RETURN_URL)。许多其他参数也可以扩展到 URL 中,例如读者 ID。有关更多详细信息,请参阅登录页面部分。
  2. 发布商显示一个自由格式的登录页面。
  3. 读者按照登录步骤操作,例如输入用户名/密码或使用社交登录。
  4. 读者提交登录。发布商完成身份验证,设置 cookie,最后将读者重定向到之前请求的“返回 URL”。重定向包含一个 URL 哈希参数 success,它可以是 truefalse
  5. 登录对话框跟随重定向到“返回 URL”。
  6. AMP 运行时重新授权该文档。

只有步骤 2-5 需要由发布商处理:发布商仅提供他们自己的登录页面,并确保在完成后进行正确的重定向。除了应该作为对话框良好运行之外,对登录页面没有其他特殊限制。

与往常一样,读者 ID 应包含在对登录页面的调用中,并且可以由发布商用于身份映射。作为第一方窗口,发布商还将收到他们的 cookie 并能够设置它们。如果发现读者已经在发布商端登录,建议发布商立即重定向回“返回 URL”并返回 success=true 响应。

AMP 词汇表

  • AMP 文档 - 遵循 AMP 格式并由 AMP 验证器验证的 HTML 文档。AMP 文档可由 Google AMP 缓存进行缓存。
  • AMP 验证器 - 执行 HTML 文档静态分析并根据文档是否符合 AMP 格式返回成功或失败的计算机程序。
  • AMP 运行时 - 执行 AMP 文档的 JavaScript 运行时。
  • Google AMP 缓存 - AMP 文档的代理缓存。
  • AMP 查看器 - 显示/嵌入 AMP 文档的 Web 或本机应用程序。
  • Publisher.com - AMP 发布商的网站。
  • CORS 端点 - 跨域 HTTPS 端点。有关更多信息,请参阅 https://mdn.org.cn/en-US/docs/Web/HTTP/Access_control_CORS。有关如何保护此类请求的信息,请参阅 CORS 来源安全
  • 读者 - 查看 AMP 文档的实际人员。
  • AMP 预渲染 - AMP 查看器可以利用预渲染,这会在文档显示之前渲染隐藏的文档。这会显著提高性能。但重要的是要考虑到文档预渲染并不构成查看,因为读者可能永远不会真正看到该文档。

修订

  • 2016-09-02:“noPingback”配置属性和可选回传。
  • 2016-03-03:登录后重新发送回传 (v0.5)。
  • 2016-02-19:更正了示例,以从 URL 变量替换中删除 {}
  • 2016-02-15:配置授权端点现在允许在授权失败时使用的“authorizationFallbackResponse”属性。
  • 2016-02-11:授权端点中的授权请求超时。
  • 2016-02-11:现在允许嵌套字段引用,例如 object.field
  • 2016-02-09:首次点击免费计量部分。
  • 2016-02-03:将“来源来源”安全规范添加到CORS 来源安全
  • 2016-02-01:可以使用 RETURN_URL URL 替换自定义登录页面的“返回”查询参数。

附录 A:“amp-access”表达式语法

最新的 BNF 语法可在access-expr-impl.jison文件中找到。

此语法的关键摘录如下

search_condition:
    search_condition OR search_condition
  | search_condition AND search_condition
  | NOT search_condition
  | '(' search_condition ')'
  | predicate

predicate:
    comparison_predicate | truthy_predicate

comparison_predicate:
    scalar_exp '=' scalar_exp
  | scalar_exp '!=' scalar_exp
  | scalar_exp '<' scalar_exp
  | scalar_exp '<=' scalar_exp
  | scalar_exp '>' scalar_exp
  | scalar_exp '>=' scalar_exp

truthy_predicate: scalar_exp

scalar_exp: literal | field_ref

field_ref: field_ref '.' field_name | field_name

literal: STRING | NUMERIC | TRUE | FALSE | NULL

请注意,amp-access 表达式由 AMP 运行时和 Google AMP 缓存评估。这不属于发布商需要实现的规范。这里只是为了提供信息。

详细讨论

本节将详细解释 amp-access 规范的底层设计,并阐明设计选择。即将推出。

验证

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

需要更多帮助?

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

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

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

转到 GitHub