访问返回 307 :
是 S3 储存桶 Region 不在 us-east-1 导致的。
CloudFront 是通过 s3 的 global endpoint 访问 s3 的,但不在 us-east-1 的 s3 刚新建时还不能通过 global endpoint 访问。
参考 so 的这个问题:
All buckets have at least two REST endpoint hostnames. In eu-west-1, they are example-bucket.s3-eu-west-1.amazonaws.com and example-bucket.s3.amazonaws.com. The first one will be immedately valid when the bucket is created. The second one -- sometimes referred to as the "global endpoint" -- which is the one CloudFront uses -- will not, unless the bucket is in us-east-1. Over a period of seconds to minutes, variable by location and other factors, it becomes globally accesible as well. Before that, the 307 redirect is returned. Hence, the bucket was not ready.
这里用 Ansible 确实是大材小用了,而且 Ansible 不能在 Windows 下用还是有点不方便,只能弃选。而 Python 和 Go 里我选了 Go Template ,原因是... 不想写 Python...
这里其实确实是装逼了,这种小型脚本应该 Python 比 Go 合适的多。不过还好 Go run 可以不先 go mod 就能运行,不算是个太差的选择。不过以后还是大概率要改回 Python 。
- name: Use Go 1.16 uses: actions/setup-go@v1 with: go-version: '1.16.1'- name: generate config run: go run ./genconfig/main.go --env=gh-pages > _config.yml
windows 玩家可能要注意一下,windows 下编码有问题, go run ./genconfig/main.go --env=gh-pages > _config.yml 这段命令直接在 PowerShell 下跑生成出来的文件不能被 Hexo 识别。不过没什么关系,反正这段到时候是在 GitHub Action Runner 上跑的,只不过是不能本地生成用来测试而已。
Here's an example of how a default root object works. Suppose the following request points to the object image.jpg:
https://d111111abcdef8.cloudfront.net/image.jpg
In contrast, the following request points to the root URL of the same distribution instead of to a specific object, as in the first example:
https://d111111abcdef8.cloudfront.net/
When you define a default root object, an end-user request that calls the root of your distribution returns the default root object. For example, if you designate the file index.html as your default root object, a request for:
https://d111111abcdef8.cloudfront.net/
Returns:
https://d111111abcdef8.cloudfront.net/index.html
However, if you define a default root object, an end-user request for a subdirectory of your distribution does not return the default root object. For example, suppose index.html is your default root object and that CloudFront receives an end-user request for the install directory under your CloudFront distribution:
https://d111111abcdef8.cloudfront.net/install/
CloudFront does not return the default root object even if a copy of index.html appears in the install directory.
If you configure your distribution to allow all of the HTTP methods that CloudFront supports, the default root object applies to all methods. For example, if your default root object is index.php and you write your application to submit a POST request to the root of your domain (http://example.com), CloudFront sends the request to http://example.com/index.php.
The behavior of CloudFront default root objects is different from the behavior of Amazon S3 index documents. When you configure an Amazon S3 bucket as a website and specify the index document, Amazon S3 returns the index document even if a user requests a subdirectory in the bucket. (A copy of the index document must appear in every subdirectory.) For more information about configuring Amazon S3 buckets as websites and about index documents, see the Hosting Websites on Amazon S3 chapter in the Amazon Simple Storage Service User Guide.
In Amazon S3, a bucket is a flat container of objects. It does not provide any hierarchical organization as the file system on your computer does. However, you can create a logical hierarchy by using object key names that imply a folder structure.
For example, consider a bucket with three objects that have the following key names. Although these are stored with no physical hierarchical organization, you can infer the following logical folder structure from the key names:
sample1.jpg — Object is at the root of the bucket.
photos/2006/Jan/sample2.jpg — Object is in the photos/2006/Jan subfolder.
photos/2006/Feb/sample3.jpg — Object is in the photos/2006/Feb subfolder.
In the Amazon S3 console, you can also create a folder in a bucket. For example, you can create a folder named photos. You can upload objects to the bucket or to the photos folder within the bucket. If you add the object sample.jpg to the bucket, the key name is sample.jpg. If you upload the object to the photos folder, the object key name is photos/sample.jpg.
If you create a folder structure in your bucket, you must have an index document at each level. In each folder, the index document must have the same name, for example, index.html. When a user specifies a URL that resembles a folder lookup, the presence or absence of a trailing slash determines the behavior of the website. For example, the following URL, with a trailing slash, returns the photos/index.html index document.
However, if you exclude the trailing slash from the preceding URL, Amazon S3 first looks for an object photos in the bucket. If the photos object is not found, it searches for an index document, photos/index.html. If that document is found, Amazon S3 returns a 302 Found message and points to the photos/ key. For subsequent requests to photos/, Amazon S3 returns photos/index.html. If the index document is not found, Amazon S3 returns an error.
If you implement CloudFront in front of S3, you can achieve this by using an OAI. However, in order to do this, you cannot use the HTTP endpoint that is exposed by S3’s static website hosting feature. Instead, CloudFront must use the S3 REST endpoint to fetch content from your origin so that the request can be authenticated using the OAI. This presents some challenges in that the REST endpoint does not support redirection to a default index page.
CloudFront does allow you to specify a default root object (index.html), but it only works on the root of the website (such as http://www.example.com > http://www.example.com/index.html). It does not work on any subdirectory (such as http://www.example.com/about/). If you were to attempt to request this URL through CloudFront, CloudFront would do a S3 GetObject API call against a key that does not exist.
'use strict';exports.handler = (event, context, callback) => { // Extract the request from the CloudFront event that is sent to Lambda@Edge var request = event.Records[0].cf.request; // Extract the URI from the request var olduri = request.uri; // Match any '/' that occurs at the end of a URI. Replace it with a default index var newuri = olduri.replace(/\/$/, '\/index.html'); // Log the URI as received by CloudFront and the new URI to be used to fetch from origin console.log("Old URI: " + olduri); console.log("New URI: " + newuri); // Replace the received URI with the URI that includes the index page request.uri = newuri; // Return to CloudFront return callback(null, request);};