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 缓存 url 会与网页域进行比较以获取新数据。现在,如果 CORS 未启用,因为它处理 amp 缓存的 url 和网页域,则请求将无效,并且 CORS 权限将失败。这就是为什么我们需要启用 CORS,即使对于 amp 页面的同源也是如此。

这里显示了使用启用了 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>

提交表单.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进行交互并取回数据。