我已经设置了 AmazonS3来服务我的静态站点 speakeasylinguistics.com。所有的 DNS 的东西似乎工作正常,因为 dig +recurse +trace www.speakeasylinguistics.com输出正确的 DNS 信息。
speakeasylinguistics.com
dig +recurse +trace www.speakeasylinguistics.com
但是,当您使用 用浏览器访问网站端点,index.html页面下载,而不是被服务。我如何解决这个问题?
index.html
我试过 Chrome,Safari,FF。所有人都会这样。我使用 亚马逊的演练托管一个自定义域到一个 T。
运行 curl-I 对照你发布的 url 会得到以下结果:
curl -I http://speakeasylinguistics.com.s3-website-us-east-1.amazonaws.com/ HTTP/1.1 200 OK x-amz-id-2: DmfUpbglWQ/evhF3pTiXYf6c+gIE8j0F6mw7VmATOpfc29V5tb5YTeojC68jE7Rd x-amz-request-id: E233603809AF9956 Date: Sun, 18 Aug 2013 07:58:55 GMT Content-Disposition: attachment Last-Modified: Sun, 18 Aug 2013 07:05:20 GMT ETag: "eacded76ceb4831aaeae2805c892fa1c" Content-Type: text/html Content-Length: 2585 Server: AmazonS3
这句话就是罪魁祸首:
Content-Disposition: attachment
如果您正在使用 AWS 控制台,我相信可以通过选择 S3中的文件并通过删除此属性来修改其元数据来更改这个属性。
如果你正在这样做的程序,你可以设置 ContentType和/或 ContentDisposition参数在您的上传。
ContentType
ContentDisposition
[ PHP 示例]
$output = $s3->putObject(array( 'Bucket' => $bucket, 'Key' => md5($share). '.html', 'ContentType' => 'text/html', 'Body' => $share, ));
PutObject 文档
如果您使用的是 Hashicorp Terraform,您可以在 Aws _ s3 _ bucket _ object上指定 content-type,如下所示
content-type
resource "aws_s3_bucket_object" "index" { bucket = "yourbucketnamehere" key = "index.html" content = "<h1>Hello, world</h1>" content_type = "text/html" }
这将在浏览器中适当地提供内容。
编辑24/05/22: 正如在这个答案的评论中提到的,Terraform 现在有了一个模块帮助上传文件并正确设置它们的 content-type属性
如果您使用的是 AWS S3 Bitbucket 管道 Python,那么添加参数 < em > content _ type 如下:
S3 _ upload.py
def upload_to_s3(bucket, artefact, bucket_key, content_type): ... def main(): ... parser.add_argument("content_type", help="Content Type File") ... if not upload_to_s3(args.bucket, args.artefact, args.bucket_key, args.content_type):
修改 管道如下:
... - python s3_upload.py bucket_name file key content_type ...
其中 Content _ type参数可以是以下内容之一: MIME 类型(IANA 媒体类型)
如果你们想用 Boto3和 python 3.7或更高版本上传,请尝试使用
s3 = boto3.client('s3') S3.upload_file(local_file,bucket,S3_file,ExtraArgs={'ContentType':'text/html'})
更新内容类型
我最近也遇到了同样的问题,问题是 CloudFront & S3 Origin 的行为发生了变化, 如果你的 S3Bucket 配置为静态网站,你需要改变你的原点为 HTTPS://端点,而不是从下拉菜单中选择 S3原点,如果你使用 terraform,你的原点应该是 aws _ S3 _ bucket。使用 var.网站 _ 端点代替 aws _ s3 _ bucket。Var.< strong > bucket _ domain _ name
请参阅 AWS 文档在这里
对于其他面临这个问题的人来说,在 Properties > Static website hosting下面的 URL 中有一个输入错误。例如,提供的 URL 是
Properties > Static website hosting
http://{bucket}.s3-website-{region}.amazonaws.com
但它应该是
http://{bucket}.s3-website.{region}.amazonaws.com
注意 website和 region之间的 .。
website
region
.
我最近遇到了这个问题,根本原因似乎是启用了对象版本控制。在桶上禁用版本控制之后,索引 HTML 按预期服务。
我也经历过同样的问题,我用这种方式解决了。 在 S3 Bucket 中,单击 o index.html 复选框,单击 con Actions 选项卡,编辑元数据,你会注意到,在元数据选项中显示“ Type: System Definition,Key: Content-Type,Value: binary/octet-stream”。 更改 价值并输入“ html”并保存更改。 然后点击 index.html,“ Open”按钮。 这招对我管用。
我在从 NodeJS 上传到 S3静态站点时遇到了同样的问题。正如其他人所提到的,这个问题是由于在上传文件时缺少 content-type引起的。当使用 web 界面时,content-type会自动为您应用; 但是,当手动上传时,您需要指定它。中三内容类别一览表.
在 NodeJS 中,您可以像下面这样附加内容类型:
const { extname } = require('path'); const { createReadStream } = require('fs'); // add more types as needed const getMimeType = ext => { switch (ext) { case '.js': return 'application/javascript'; case '.html': return 'text/html'; case '.txt': return 'text/plain'; case '.json': return 'application/json'; case '.ico': return 'image/x-icon'; case '.svg': return 'image/svg+xml'; case '.css': return 'text/css' case '.jpg': case '.jpeg': return 'image/jpeg'; case '.png': return 'image/png'; case '.webp': return 'image/webp'; case '.map': return 'binary/octet-stream' default: return 'application/octet-stream' } }; (async() => { const file = './index.html'; const params = { Bucket: 'myBucket', Key: file, Body: createReadStream(file), ContentType: getMimeType(extname(file)), }; await s3.putObject(params).promise(); })();
下面是在设置 content-type 时将目录(包括子目录)上载到 s3的解决方案。
locals { mime_types = { ".html" = "text/html" ".css" = "text/css" ".js" = "application/javascript" ".ico" = "image/vnd.microsoft.icon" ".jpeg" = "image/jpeg" ".png" = "image/png" ".svg" = "image/svg+xml" } } resource "aws_s3_object" "upload_assets" { bucket = aws_s3_bucket.www_bucket.bucket for_each = fileset(var.build_path, "**") key = each.value source = "${var.build_path}/${each.value}" content_type = lookup(local.mime_types, regex("\\.[^.]+$", each.value), null) etag = filemd5("${var.build_path}/${each.value}") }
var.build_path是包含您的资产的目录。这一行:
var.build_path
content_type = lookup(local.mime_types, regex("\\.[^.]+$", each.value), null)
通过匹配正则表达式获取文件扩展名,然后使用提供的局部变量映射来查找正确的 content_type
content_type
提供者: https://engineering.statefarm.com/blog/terraform-s3-upload-with-mime/