gpt4 book ai didi

html - 提供索引文件而不是下载提示

转载 作者:行者123 更新时间:2023-12-03 22:57:32 24 4
gpt4 key购买 nike

我的网站托管在 S3 上,CloudFront 作为 CDN,我需要这两个 URL 的行为相同并为目录中的 index.html 文件提供服务:
example.com/directoryexample.com/directory/
末尾带有 / 的那个错误地提示浏览器下载一个零字节文件,该文件带有文件名的随机散列。如果没有斜线,它会返回我的 404 页面。

如何获得两个路径以在目录中传送 index.html 文件?

如果有一种方法我“应该”做到这一点,太好了!这就是我所希望的,但如果不是,我可能会尝试使用 Lambda@Edge 进行重定向。无论如何,我需要在其他一些情况下使用它,因此有关如何从 Lambda@Edge 进行 301 或 302 重定向的一些说明也会有所帮助:)

更新(根据 John Hanley 的评论)
curl -i https://www.example.com/directory/

HTTP/2 200 
content-type: application/x-directory
content-length: 0
date: Sat, 12 Jan 2019 22:07:47 GMT
last-modified: Wed, 31 Jan 2018 00:44:16 GMT
etag: "[id]"
accept-ranges: bytes
server: AmazonS3
x-cache: Miss from cloudfront
via: 1.1 [id].cloudfront.net (CloudFront)
x-amz-cf-id: [id]

更新

CloudFront 有一个行为集,将 http 转发到 https 并将请求发送到 S3。它在错误选项卡下还有一个 404 错误路由。

最佳答案

S3 仅在您启用并使用存储桶的网站托管功能时提供自动索引文档,方法是指向存储桶的网站托管端点 ${bucket}.s3-website.${region}.amazonaws.com 而不是存储桶的通用 REST 端点 ${bucket}.s3.amazonaws.com

网站端点和 REST 端点都有 numerous differences ,包括这个。

您看到这些以 / 结尾的对象键的 0 字节文件的原因是因为您正在使用 S3 控制台或其他实际创建 0 字节对象的实用程序在存储桶中创建文件夹对象。一旦文件夹中有对象,它们就不再需要了——但它们是在 S3 控制台中显示空文件夹的唯一方法,它将名为 foo/ 的对象显示为名为 foo 的文件夹,即使有没有其他键前缀为 foo/ 的对象。它是控制台中文件夹层次结构的视觉模拟的一部分,即使 S3 中的对象从未真正“在”文件夹中。

如果出于某种原因您需要使用 REST 端点——例如您不想将存储桶设为公开——那么您需要在 CloudFront 中使用两个 Lambda@Edge 触发器,以相当接近地模拟此功能。

在检查 CloudFront 缓存之后,在将请求发送到源之前,源请求触发器可以检查和修改请求。我们使用它来检查以 / 结尾的路径,如果找到,则附加 index.html

在将响应写入 CloudFront 缓存之前,源响应触发器可以检查并可能修改响应。源响应触发器还可以检查生成响应的请求之前的原始请求。我们使用它来检查响应是否为错误。如果是,并且原始请求确实 而不是 似乎是针对索引文档或文件(具体来说,在路径中的最后一个斜杠之后,"file"至少有一个字符,后跟一个点,后跟至少还有一个字符——如果是这样,那可能是一个"file")。如果这两者都不是,我们将重定向到原始路径以及我们附加的最终 /

Origin Request 和 Origin Response 仅在缓存未命中时触发 触发 。当缓存命中时,两个触发器都不会触发,因为它们位于 CloudFront 的源端——缓存的背面。可以从缓存服务的请求是从缓存服务的,因此不会调用触发器。

下面是一个用 Node.js 8.10 编写的 Lambda@Edge 函数。这个 Lambda 函数修改了它的行为,使其根据上下文表现为原始请求或原始响应。在 Lambda 中发布版本后,将该版本的 ARN 与 CloudFront 缓存行为设置关联为 源请求和源响应触发器。

'use strict';

// combination origin-request, origin-response trigger to emulate the S3
// website hosting index document functionality, while using the REST
// endpoint for the bucket

// https://stackoverflow.com/a/54263794/1695906

const INDEX_DOCUMENT = 'index.html'; // do not prepend a slash to this value

const HTTP_REDIRECT_CODE = '302'; // or use 301 or another code if desired
const HTTP_REDIRECT_MESSAGE = 'Found';

exports.handler = (event, context, callback) => {
const cf = event.Records[0].cf;

if(cf.config.eventType === 'origin-request')
{
// if path ends with '/' then append INDEX_DOCUMENT before sending to S3
if(cf.request.uri.endsWith('/'))
{
cf.request.uri = cf.request.uri + INDEX_DOCUMENT;
}
// return control to CloudFront, to send request to S3, whether or not
// we modified it; if we did, the modified URI will be requested.
return callback(null, cf.request);
}
else if(cf.config.eventType === 'origin-response')
{
// is the response 403 or 404? If not, we will return it unchanged.
if(cf.response.status.match(/^40[34]$/))
{
// it's an error.

// we're handling a response, but Lambda@Edge can still see the attributes of the request that generated this response; so, we
// check whether this is a page that should be redirected with a trailing slash appended. If it doesn't look like an index
// document request, already, and it doesn't end in a slash, and doesn't look like a filename with an extension... we'll try that.

// This is essentially what the S3 web site endpoint does if you hit a nonexistent key, so that the browser requests
// the index with the correct relative path, except that S3 checks whether it will actually work. We are using heuristics,
// rather than checking the bucket, but checking is an alternative.

if(!cf.request.uri.endsWith('/' + INDEX_DOCUMENT) && // not a failed request for an index document
!cf.request.uri.endsWith('/') && // unlikely, unless this code is modified to pass other things through on the request side
!cf.request.uri.match(/[^\/]+\.[^\/]+$/)) // doesn't look like a filename with an extension
{
// add the original error to the response headers, for reference/troubleshooting
cf.response.headers['x-redirect-reason'] = [{ key: 'X-Redirect-Reason', value: cf.response.status + ' ' + cf.response.statusDescription }];
// set the redirect code
cf.response.status = HTTP_REDIRECT_CODE;
cf.response.statusDescription = HTTP_REDIRECT_MESSAGE;
// set the Location header with the modified URI
// just append the '/', not the "index.html" -- the next request will trigger
// this function again, and it will be added without appearing in the
// browser's address bar.
cf.response.headers['location'] = [{ key: 'Location', value: cf.request.uri + '/' }];
// not strictly necessary, since browsers don't display it, but remove the response body with the S3 error XML in it
cf.response.body = '';
}
}

// return control to CloudFront, with either the original response, or
// the modified response, if we modified it.

return callback(null, cf.response);

}
else // this is not intended as a viewer-side trigger. Throw an exception, visible only in the Lambda CloudWatch logs and a 502 to the browser.
{
return callback(`Lambda function is incorrectly configured; triggered on '${cf.config.eventType}' but expected 'origin-request' or 'origin-response'`);
}

};

关于html - 提供索引文件而不是下载提示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54164128/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com