【问题标题】:S3 static pages without .html extension没有 .html 扩展名的 S3 静态页面
【发布时间】:2014-05-05 01:50:05
【问题描述】:

在为 Amazon S3 的静态站点提供服务时,我想知道如何摆脱每个页面的 .html 文件扩展名。

现在我有:

mysite.com/             # works fine, serves index.html
mysite.com/mypage.html  # works fine
mysite.com/mypage       # doesn't work

/mypage 的错误显示:

404 Not Found

Code: NoSuchKey
Message: The specified key does not exist.
Key: mypage
RequestId: 1089D7A26EFED9AD
HostId: Ud8cFy8Zl1mJ+oFjFOmU1Xacq9+v70KuaJfOc4nFMEPhd66AkLhr4Pj5u0QH6Gog

我尝试按照this postContent-Type 设置为text/html,但这并不能解决我的问题。

如何让 /mypage 在 S3 上的 /mypage.html 上提供文件?

【问题讨论】:

    标签: html amazon-web-services amazon-s3


    【解决方案1】:

    我刚遇到这个问题,我想分享解决方案:

    您必须将文件Content-type 的元数据设置为text/html 并重命名文件,删除末尾的.html

    这样您就可以在没有文件扩展名的情况下访问每个页面。

    【讨论】:

    • 如何在命令行工具中编辑Content-type 标头?还是在 S3 或 Cloudfront 的控制台中?
    • @Costa,我在控制台 (Windows) 中使用以下内容成功修改了 Content-type 标头:aws s3 cp C:\folder\file s3://folder/file --content-type "text/html" 参考:docs.aws.amazon.com/cli/latest/reference/s3/cp.html
    • 我在网上看到过这个解决方案,但删除文件扩展名让我觉得很脏。这仍然是 S3 上漂亮 URL 的推荐方法吗?
    • 直到我将 html 标头从我正在使用的 <html xmlns="http://www.w3.org/1999/xhtml" > 更改为 <!doctype html> 之后,这才起作用。
    • 我的 .html 文件太多,是否有任何自动脚本可以从文件名中删除 .html?
    【解决方案2】:

    通常在 Amazon S3 上,要创建干净的 URL,您可以:

    1. 使用“干净”名称上传页面文件,例如mypage 并将Content-Type 设置为text/html(如您链接到的帖子所述)。您必须在上传之前将系统上的文件重命名为没有扩展名,或者在上传后在 S3 上重命名为没有扩展名的rename。 S3 上的文件名不得有扩展名。

    2. 使用“干净”名称创建一个文件夹,并将页面文件上传到该文件夹​​,并将其名称设置为 default index document,例如index.html。您需要检查默认索引文档名称是什么。这是在您将存储桶配置为网站时设置的,但以后可以更改。

    如果您无法完成上述工作,您可以使用名称键 mypage 上传一个新的零字节对象,然后通过在元数据中指定带有值 mypage.htmlWebsite Redirect Location 键来设置页面重定向在上传过程中。请参阅 Amazon S3 文档中的配置网页重定向。

    您还可以将文件复制到名为 mypage 的新对象,并将 Content-Type 设置为 text/html

    【讨论】:

    • 零字节对象方法执行从mypagemypage.html 的重定向,因此并没有真正摆脱.html 扩展。我还尝试了您在 1 和 2 中的两种方法,但都不适合我。任何想法为什么会这样?
    • 重定向是我把你的问题“我如何让 /mypage 在 /mypage.html 提供文件”的意思。您在下面说我在(2)中的方法有效。 “索引文档”可以设置为任何内容(我无法在我的答案中添加亚马逊文档的链接)。对于方法(1),您将要服务的页面命名为什么?
    • 如何更改s3上的内容类型?还是云端?
    【解决方案3】:

    正如一些人已经说过的,删除文件扩展名,然后只需按照以下步骤操作:

    1. 转到您的 Amazon S3 存储桶。
    2. 选中您希望正确链接的文件旁边的复选框。
    3. 单击右侧的“属性”,将显示一个新窗格。它会说“对象:文件名”
    4. 单击元数据选项卡,更改默认值,对我来说是“二进制/八位字节流”;新值应该是“text/html”。
    5. 保存。

    正如人们所说,确保 html 中的新链接不再包含 .html 文件扩展名。这对我有用。

    【讨论】:

      【解决方案4】:

      /mypage 创建一个文件夹并将index.html 放入其中对我不起作用。原来这是因为 Bucket 的“Index Document”设置改成了myindex.html

      Bucket Properties --> Static Website Hosting --> Enable Website Hosting --> Index Document
      

      这实际上也适用于所有子文件夹,因此在 /mypage 路由上时它不会寻找 /mypage/index.html;它正在寻找/mypage/myindex.html

      我只是将myindex.html 设置改回index.html,标准文件夹结构就可以工作了。在任何地方使用 myindex.html 文件并设置该设置也同样有效,但这似乎没有真正的收获。

      我仍然不知道为什么将 Content-Type 设置为 text/html 不起作用 - 似乎应该像在几个地方提到的那样。

      无论如何,通过将Bucket的Index Document和所有子文件夹更改为使用index.html来解决问题。

      【讨论】:

      • 我不知道是否发生了变化,但是除了存储桶本身之外,没有其他选项可以设置默认索引页面。此外,存储桶中目录的属性不允许您设置它们。所以这种技术似乎不起作用。如果这个答案仍然有效,我将不胜感激。谢谢。
      • 我也试过了,还是不行。如果您将 index.html 或其他任何内容用作“索引文档”,则此配置不适用于子文件夹。
      【解决方案5】:

      使用 AWS CLI:

      假设您已从文件名中删除扩展名并使用您的账户设置 AWS CLI,您可以通过在控制台中运行以下命令来设置文件的元数据:

      aws s3 cp /path/to/file s3://yourwebsite.com --content-type 'text/html' --acl public-read
      

      【讨论】:

        【解决方案6】:

        在多页网络应用程序(例如 12 页)中,接受的答案将是低效的,因为每次上传都需要手动编辑文件扩展名和格式。

        使用 AWS Lamda@Edge 是一种自动化且无忧的策略。它完全解决了这个问题。

        首先,创建一个 AWS Lambda 函数,然后附加您的 CloudFront 作为触发器。

        在此 AWS Lamda 页面的代码部分,将 sn-p 添加到下面的存储库中。

        https://github.com/CloudUnder/lambda-edge-nice-urls/blob/master/lambdaRewrite.js

        内容交付速度仍将与您眨眼一样快。

        PS:注意上面 repo 的 readme 部分中的选项

        【讨论】:

          【解决方案7】:

          非常简单且经过测试的解决方案。 :

          1. 重命名文件,从文件名中删除扩展名 (.html)。 (例如,将gallery.html 更改为gallery)。
          2. 编辑文件的属性。添加元数据键(内容类型 = text/html 和内容语言 = html)。
          3. 从浏览器 url(如 websiteurl.com/gallery)保存并测试。

          【讨论】:

            【解决方案8】:

            如果你想上传 json 文件。将不带扩展名的 json 文件保存在本地机器中。

            从 AWS CLI 使用以下命令:

              aws s3 mb s3://<s3bucketname>
            
              #output 
              make_bucket: s3bucketname
            
              aws s3 cp path\to\local\file s3://<s3bucketname>  --content-type 'application/json' --acl public-read
            
              #output
              upload: .\<filename> to s3://<s3bucketname>/<filename>
            

            现在您可以使用 url 访问文件:

            https://&lt;s3bucketname&gt;.s3.amazonaws.com/&lt;filename&gt;

            【讨论】:

              【解决方案9】:

              我添加了一些自动化脚本示例以删除 *.HTML 扩展名并通过添加元对象的内容类型上传到 s3。我使用 javascript 创建 sh 文件,我运行 sh 文件。

              const recursive = require("recursive-readdir");
              const fs = require("fs");
              
              (async (params) => {
               let buffer = "aws s3 cp ./out s3://www.Example.com \n";
                await recursive("out", [
                  "css",
                  "_next",
                  "images",
                  "static",
                  "svg",
                  "*.ico",
                  "*.txt",
                  "*.xml",
                  "index.html",
                  "404.html",
                ]).then(
                  (files) => {
                   
                  
                    for (const file of files) {
                      const path = file.substring(file.indexOf("\\") + 1);
              
                      buffer += `aws s3 cp --content-type 'text/html' --metadata-directive REPLACE ./out/${path}  s3://www.example.com/${path} \n`;
              
                      const removeExtension = file.replace(/\.[^/.]+$/, "");
              
                      fs.rename(file, removeExtension, function (err) {
                        if (err) console.log("ERROR: " + err);
                      });
                    }
                 
                  },
                  (error) => {
                    console.error("something exploded", error);
                  }
                );
              
                
              
              
                fs.writeFileSync("deploy.sh", "echo 'copy your files' \n");
                fs.appendFileSync("deploy.sh", buffer);
              
                fs.appendFileSync("deploy.sh", 'echo "Invalidation cloudfront"');
                fs.appendFileSync("deploy.sh", 'aws cloudfront create-invalidation --distribution-id XXXXXXX --paths "/*" ');
              
              
              
              
              
              })();
              
              

              【讨论】:

                【解决方案10】:

                它在根域上没有尾随斜杠的原因是因为您的主索引具有这种结构:

                mysite.com/index.html

                然后服务器去服务器索引默认页面,显示:

                mysite.com/

                如果您不希望所有页面都使用斜杠,您应该对所有 html 文件执行相同的操作。而不是

                mysite.com/mypage.html

                mysite.com/mypage/index.html

                然后服务器会显示mypage文件夹的默认索引文件,显示在url中

                mysite.com/mypage/

                【讨论】:

                  【解决方案11】:

                  另一种可能的解决方案是使用 Lambda@edge power,documentation reference here

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 2012-08-09
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2015-05-17
                    • 2018-02-04
                    • 1970-01-01
                    相关资源
                    最近更新 更多