Google AMP - Cors
在本章中,我们将尝试了解 AMP 中的 CORS。在深入了解细节之前,让我们先了解一下 CORS 的基础知识及其用途。
什么是 CORS?
CORS 代表跨源资源共享。CORS 是一个需要额外 HTTP 标头数据的过程,用于告诉浏览器是否应该授予在 xyz.com 源运行的网页对 URL 发出的请求以访问请求 URL 中的数据的权限。我们从网页发出许多 http 请求,为此我们需要有 CORS 来获取所需的数据。
当我们向主机以外的服务器发出 http 请求时,我们将其称为跨源请求,这意味着域、协议和端口与主机源不同。在这种情况下,应该有来自请求的 URL 的访问数据的权限;表示已发出 GET/PUT/POST/DELETE 请求。
此附加数据可在浏览器标头中用于发出的 http 请求调用。此步骤的权限基本上是出于安全原因而必需的,以便没有所需权限的网页无法从其他域创建或获取数据。
浏览器的标头应包含详细信息,例如 Access-Control-Allow-Origin,其值可以如下所示 −
Access-Control-Allow-Origin : *
请求 URL 标头具有值 * 意味着它告诉浏览器允许从任何来源请求数据来访问资源。
Access-Control-Allow-Origin: https://www.example.com
具有上述值会告诉浏览器,来自网页 www.example.com 的请求将仅被允许获取所请求 URL 的数据。
服务器配置在使用 CORS 时,必须牢记共享数据的使用方式。根据此情况,必须在服务器端设置所需的标头。
现在我们知道了什么是 CORS,让我们再进一步。对于 amp,我们有 amp-form、amp-list 等组件,它们使用 http 端点动态加载数据。
对于 amp 页面,即使 http 请求来自同一来源,我们也需要设置 CORS。这里出现了一个问题 - 为什么即使请求和响应来自同一来源,我们也要启用 CORS。从技术上讲,在这种情况下我们不需要启用 CORS,因为我们正在请求和显示同一域、来源等的数据。
Amp 有一个称为缓存的功能,它被添加以便更快地将数据发送给访问页面的用户。如果用户已经访问过该页面,数据将缓存在 google cdn 上,下一个用户将从缓存中获取数据。
数据存储在 amp 端,现在具有不同的域。当用户单击任何按钮以获取新数据时,将 amp 缓存 url 与网页域进行比较以获取新数据。现在,如果未启用 CORS,因为它处理 amp 缓存 url 和网页域,则请求将无效,并且将因 CORS 权限而失败。这就是为什么我们需要在 amp 页面的情况下启用 CORS,即使对于同源也是如此。
此处显示了使用启用了 CORS 的表单的工作示例 −
<!doctype html> <html amp lang = "en"> <head> <meta charset = "utf-8"> <script async src = "https://cdn.ampproject.org/v0.js"> </script> <title>Google AMP - Form</title> <link rel = "canonical" href = "ampform.html"> <meta name = "viewport" content = "width = device-width, minimum-scale = 1,initial-scale = 1"> <style amp-boilerplate> body{ -webkit-animation: -amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation: -amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation: -amp-start 8s steps(1,end) 0s 1 normal both;animation: -amp-start 8s steps(1,end) 0s 1 normal both } @-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}} </style> <noscript> <style amp-boilerplate> body{ -webkit-animation:none; -moz-animation:none; -ms-animation:none; animation:none} </style> </noscript> <script async custom-element = "amp-form" src = "https://cdn.ampproject.org/v0/amp-form-0.1.js"> </script> <script async custom-template = "amp-mustache" src = "https://cdn.ampproject.org/v0/amp-mustache-0.2.js"> </script> <style amp-custom> form.amp-form-submit-success [submit-success], form.amp-form-submit-error [submit-error]{ margin-top: 16px; } form.amp-form-submit-success [submit-success] { color: white; background-color:gray; } form.amp-form-submit-error [submit-error] { color: red; } form.amp-form-submit-success.hide-inputs > input { display: none; } </style> </head> <body> <h3>Google AMP - Form</h3> <form method = "post" class = "p2" action-xhr = "submitform.php" target = "_top"> <p>AMP - Form Example</p> <div> <input type = "text" name = "name" placeholder = "Enter Name" required> <br/> <br/> <input type = "email" name = "email" placeholder = "Enter Email" required> <br/> <br/> </div> <input type = "submit" value = "Submit"> <div submit-success> <template type = "amp-mustache"> Form Submitted! Thanks {{name}}. </template> </div> <div submit-error> <template type = "amp-mustache"> Error! {{name}}, please try again. </template> </div> </form> </body> </html>
submitform.php
<?php if(!empty($_POST)){ $domain_url = (isset($_SERVER['HTTPS']) ? "https" : "http") . "://$_SERVER[HTTP_HOST]"; header("Content-type: application/json"); header("AMP-Access-Control-Allow-Source-Origin: " . $domain_url); header("Access-Control-Expose-Headers: AMP-Access-Control-Allow-Source-Origin"); $myJSON = json_encode($_POST); echo $myJSON; } ?>
输出

添加到 submitform.php 的响应标头的详细信息 −

为了使表单正常工作,我们需要添加标头,例如 access-control-expose-headers,其值为 AMP-Access-Control-Allow-Source-Origin 和 amp-access-control-allow-source-origin − http://localhost:8080。
这里我们使用 php 文件,使用的服务器是 apache。在 php 文件中,我们添加了所需的标头,如下所示 −
<?php if(!empty($_POST)){ $domain_url = (isset($_SERVER['HTTPS']) ? "https" : "http") . "://$_SERVER[HTTP_HOST]"; header("Content-type: application/json"); header("AMP-Access-Control-Allow-Source-Origin: " . $domain_url); header("Access-Control-Expose-Headers: AMP-Access-Control-Allow-Source-Origin"); $myJSON = json_encode($_POST); echo $myJSON; } ?>
添加所需的标头后,将允许源 http://localhost:8080 进行交互并获取数据。