Amazon web services 是否将CloudFront配置为代理查询字符串作为S3对象键的一部分?

Amazon web services 是否将CloudFront配置为代理查询字符串作为S3对象键的一部分?,amazon-web-services,amazon-s3,proxy,query-string,amazon-cloudfront,Amazon Web Services,Amazon S3,Proxy,Query String,Amazon Cloudfront,我们将AWS CloudFront配置为将请求代理到S3存储桶上 AWS CloudFront允许您对其进行配置,以便查询字符串参数也被代理到源服务器()-我们也配置了此选项 我遇到的问题是,查询字符串param似乎没有包含在S3对象键查找中 例如,我们有如下对象键: foo foo?a=1 foo?b=2 但是如果我们提出这样的请求,或者我们最终得到的是/foo内容,而不是特定的关键内容 看起来CloudFront可能正在代理查询字符串参数,但它们并没有用作S3对象键查找过程的一部分 以前

我们将AWS CloudFront配置为将请求代理到S3存储桶上

AWS CloudFront允许您对其进行配置,以便查询字符串参数也被代理到源服务器()-我们也配置了此选项

我遇到的问题是,查询字符串param似乎没有包含在S3对象键查找中

例如,我们有如下对象键:

  • foo
  • foo?a=1
  • foo?b=2
但是如果我们提出这样的请求,或者我们最终得到的是
/foo
内容,而不是特定的关键内容

看起来CloudFront可能正在代理查询字符串参数,但它们并没有用作S3对象键查找过程的一部分

以前有人经历过吗?和/或知道解决方案


谢谢

使用web浏览器,CloudFront和S3(如果直接访问)在对象键中使用
时都不会像您所期望的那样工作,因为在HTTP中,未扫描的
是查询字符串的分隔符

根据定义,该
标记路径的结束,从而标记对象键的结束

获取键中带有
的对象的唯一方法是浏览器发送请求,并将
转义为
%3F
,这意味着URL最初必须以这种方式呈现给浏览器

您不能将对象上载到键名中带有
的S3,然后从URL中带有文本
的浏览器访问它

使用
curl
演示,但浏览器行为相同

在URI中使用
/foo?bar

$ curl -v 'http://.....s3.amazonaws.com/foo?bar=1'
* About to connect() to .....s3.amazonaws.com port 80 (#0)
*   Trying x.x.x.x... connected
> GET /foo?bar=1 HTTP/1.1

< HTTP/1.1 404 Not Found

<?xml version="1.0" encoding="UTF-8"?>
<Error>
  <Code>NoSuchKey</Code>
  <Message>The specified key does not exist.</Message>
  <Key>foo</Key>                                      <<< requested object is "foo"
  <RequestId>...</RequestId>
  <HostId>...</HostId>
</Error>
$ curl -v 'http://.....s3.amazonaws.com/foo%3Fbar=1'
* About to connect() to .....s3.amazonaws.com port 80 (#0)
*   Trying x.x.x.x... connected
> GET /foo%3Fbar=1 HTTP/1.1

< HTTP/1.1 404 Not Found

<?xml version="1.0" encoding="UTF-8"?>
<Error>
  <Code>NoSuchKey</Code>
  <Message>The specified key does not exist.</Message>
  <Key>foo?bar=1</Key>                                <<< requested object is "foo?bar=1"
  <RequestId>...</RequestId>
  <HostId>...</HostId>
</Error>
URI中的
/foo%3Fbar=1

$ curl -v 'http://.....s3.amazonaws.com/foo?bar=1'
* About to connect() to .....s3.amazonaws.com port 80 (#0)
*   Trying x.x.x.x... connected
> GET /foo?bar=1 HTTP/1.1

< HTTP/1.1 404 Not Found

<?xml version="1.0" encoding="UTF-8"?>
<Error>
  <Code>NoSuchKey</Code>
  <Message>The specified key does not exist.</Message>
  <Key>foo</Key>                                      <<< requested object is "foo"
  <RequestId>...</RequestId>
  <HostId>...</HostId>
</Error>
$ curl -v 'http://.....s3.amazonaws.com/foo%3Fbar=1'
* About to connect() to .....s3.amazonaws.com port 80 (#0)
*   Trying x.x.x.x... connected
> GET /foo%3Fbar=1 HTTP/1.1

< HTTP/1.1 404 Not Found

<?xml version="1.0" encoding="UTF-8"?>
<Error>
  <Code>NoSuchKey</Code>
  <Message>The specified key does not exist.</Message>
  <Key>foo?bar=1</Key>                                <<< requested object is "foo?bar=1"
  <RequestId>...</RequestId>
  <HostId>...</HostId>
</Error>
这是URL形成方式的限制,而不是S3(或CloudFront)。。。但是S3文档中提到了:

键名中的以下字符可能需要额外的代码处理,并且可能需要URL编码或作为十六进制引用

问号(“?”)

如果您能够使用SDK正确上载此类对象,那么它将为您转义字符。web浏览器不会隐式地这样做,因为
具有特定的含义


无论CloudFront是否将查询字符串传递给S3,网络行为都是相同的——查询字符串不是键的一部分。

使用web浏览器,CloudFront和S3(如果直接访问)都不会像您预期的那样在对象键中使用
,因为在HTTP中,未scaped的
是查询字符串的分隔符

根据定义,该
标记路径的结束,从而标记对象键的结束

获取键中带有
的对象的唯一方法是浏览器发送请求,并将
转义为
%3F
,这意味着URL最初必须以这种方式呈现给浏览器

您不能将对象上载到键名中带有
的S3,然后从URL中带有文本
的浏览器访问它

使用
curl
演示,但浏览器行为相同

在URI中使用
/foo?bar

$ curl -v 'http://.....s3.amazonaws.com/foo?bar=1'
* About to connect() to .....s3.amazonaws.com port 80 (#0)
*   Trying x.x.x.x... connected
> GET /foo?bar=1 HTTP/1.1

< HTTP/1.1 404 Not Found

<?xml version="1.0" encoding="UTF-8"?>
<Error>
  <Code>NoSuchKey</Code>
  <Message>The specified key does not exist.</Message>
  <Key>foo</Key>                                      <<< requested object is "foo"
  <RequestId>...</RequestId>
  <HostId>...</HostId>
</Error>
$ curl -v 'http://.....s3.amazonaws.com/foo%3Fbar=1'
* About to connect() to .....s3.amazonaws.com port 80 (#0)
*   Trying x.x.x.x... connected
> GET /foo%3Fbar=1 HTTP/1.1

< HTTP/1.1 404 Not Found

<?xml version="1.0" encoding="UTF-8"?>
<Error>
  <Code>NoSuchKey</Code>
  <Message>The specified key does not exist.</Message>
  <Key>foo?bar=1</Key>                                <<< requested object is "foo?bar=1"
  <RequestId>...</RequestId>
  <HostId>...</HostId>
</Error>
URI中的
/foo%3Fbar=1

$ curl -v 'http://.....s3.amazonaws.com/foo?bar=1'
* About to connect() to .....s3.amazonaws.com port 80 (#0)
*   Trying x.x.x.x... connected
> GET /foo?bar=1 HTTP/1.1

< HTTP/1.1 404 Not Found

<?xml version="1.0" encoding="UTF-8"?>
<Error>
  <Code>NoSuchKey</Code>
  <Message>The specified key does not exist.</Message>
  <Key>foo</Key>                                      <<< requested object is "foo"
  <RequestId>...</RequestId>
  <HostId>...</HostId>
</Error>
$ curl -v 'http://.....s3.amazonaws.com/foo%3Fbar=1'
* About to connect() to .....s3.amazonaws.com port 80 (#0)
*   Trying x.x.x.x... connected
> GET /foo%3Fbar=1 HTTP/1.1

< HTTP/1.1 404 Not Found

<?xml version="1.0" encoding="UTF-8"?>
<Error>
  <Code>NoSuchKey</Code>
  <Message>The specified key does not exist.</Message>
  <Key>foo?bar=1</Key>                                <<< requested object is "foo?bar=1"
  <RequestId>...</RequestId>
  <HostId>...</HostId>
</Error>
这是URL形成方式的限制,而不是S3(或CloudFront)。。。但是S3文档中提到了:

键名中的以下字符可能需要额外的代码处理,并且可能需要URL编码或作为十六进制引用

问号(“?”)

如果您能够使用SDK正确上载此类对象,那么它将为您转义字符。web浏览器不会隐式地这样做,因为
具有特定的含义


无论CloudFront是否将查询字符串传递给S3,网络行为都是一样的——查询字符串不是键的一部分。

看起来您发送的方式就像CloudFront转换它一样。您需要像下面这样查询对象

您需要对这些字符执行URI编码,以便将它们作为对象名传递给S3


希望能有所帮助。

看起来您正在以这样一种方式发送,它会被CloudFront翻译。您需要像下面这样查询对象

您需要对这些字符执行URI编码,以便将它们作为对象名传递给S3


希望能有帮助。

Doh,当然可以。这很有道理。不知道我怎么会错过。谢谢你把这件事弄清楚…是的,不过当然。这很有道理。不知道我怎么会错过。谢谢你澄清此事。。