读取S3对象的ajax GET请求的所有响应头

读取S3对象的ajax GET请求的所有响应头,ajax,google-chrome,amazon-web-services,amazon-s3,Ajax,Google Chrome,Amazon Web Services,Amazon S3,问题概述: 我通过预签名文件的CORS请求访问存储在AWS S3存储桶中的文件列表。这基本上很好用。但是,这些对象附加了一些自定义元数据,我无法访问这些元数据。我明白,只有当我添加头密钥(例如x-amz-meta-1234)时,我才能访问此元数据,其中1234是我元数据的密钥,用于目标bucket的CORS配置的公开头。虽然到目前为止这对我有效,但我无法使用通配符(如x-amz-meta-*)设置公开标题,这将解决我的问题,但AWS不支持公开标题项的通配符 但是,当我查看Chrome开发工具的网

问题概述: 我通过预签名文件的CORS请求访问存储在AWS S3存储桶中的文件列表。这基本上很好用。但是,这些对象附加了一些自定义元数据,我无法访问这些元数据。我明白,只有当我添加头密钥(例如x-amz-meta-1234)时,我才能访问此元数据,其中1234是我元数据的密钥,用于目标bucket的CORS配置的公开头。虽然到目前为止这对我有效,但我无法使用通配符(如x-amz-meta-*)设置公开标题,这将解决我的问题,但AWS不支持公开标题项的通配符

但是,当我查看Chrome开发工具的网络选项卡时,所有需要的元数据都显示在GET/HEAD请求期间的标题中。注意下半部分的条目,x-amz-meta-4021和-template_id:

这是我的决定:

            $.ajax({
                url: url,                      
                dataType: 'json',
                crossDomain: true,
                type: 'HEAD',
                success: function(data, status, jqXHR) {
                    console.log('got some response ..?');
                    console.log(data);
                    console.log(jqXHR);
                    console.log('responseHeader template_id: ' + jqXHR.getResponseHeader('x-amz-meta-template_id'));
                    console.log('responseHeader meta-4021: ' + jqXHR.getResponseHeader('x-amz-meta-4021'));
                    console.log(jqXHR.getAllResponseHeaders());
                },
                error: function(error, xhr, data) {
                    console.log('in error..');
                    console.log(error);
                    console.log(xhr);
                    console.log(data);
                }
            });
        });
这是控制台输出:

Object {readyState: 4, getResponseHeader: function, getAllResponseHeaders: 
function, setRequestHeader: function, overrideMimeType: function…}
responseHeader template_id: 813
responseHeader meta-4021: null
x-amz-meta-template_id: 813
Last-Modified: Fri, 09 Jun 2017 13:05:33 GMT
Content-Type: video/mp4
我显式地为元数据项“template_id”设置了expose头,因此正确地返回了该项的头数据。但是,对于条目“4021”,我没有设置expose头。问题是,这些元数据和密钥是由我们的android/ios应用程序生成的,我真的不能那么容易地控制这些元数据的密钥

让我困惑的是:为什么我能够在chrome网络选项卡中看到整个响应,但不能从客户端脚本访问这些数据?有许多可能的解决方法和解决方案,但我基本上想了解,为什么我的浏览器可以显示jQuery无法访问的数据

PS:如果你想查看CORS配置或完整脚本,请告诉我。我尽量做到精确。提前谢谢

我基本上想理解,为什么我的浏览器可以显示jQuery无法访问的数据

要理解这一点,您需要理解CORS的目的

CORS并不是真正的访问控制,CORS也不是真正代表你的网站。CORS代表用户和浏览器工作,以防止浏览器成为一个用户,并做一些用户不想做的事情。这通常与网站不想要的东西相吻合,但这是次要的

浏览器的默认行为是假定对跨源请求的编程访问是错误的,这就是为什么在不存在访问控制允许源标题时拒绝这些请求的原因。您的银行不希望internetbadguys.com向银行网站发出ajax请求,如果该网站尝试,浏览器将阻止该请求,除非银行的web服务器愚蠢地通过CORS响应允许该请求

CORS是一种让你的网站告诉浏览者的机制,是的,你提出的跨来源请求不是意外的,它是允许的。。。从这个响应中,允许浏览器执行某些行为,例如向发出请求的代码公开以下响应头


因此,你观察到的行为是正确的。公开或不公开头并不意味着在HTTP响应中包含它们或不公开头——公开头允许浏览器向ajax调用方公开它所知道的内容。如果跨源代码希望将其公开,则必须明确。

谢谢您提供的详细信息!公开或不公开头并不意味着在HTTP响应中包含它们——在本例中,我只是观察了行为,但我理解您的观点。简言之,我需要让元数据以一种不太通用的方式定义,而不需要对这个问题进行太多的详细说明,或者找到另一种机制来存储我的元数据。我会在1-2天内将您的回复标记为答案,可能会出现其他一些有趣的问题。如果您的整个应用程序以及存储桶都配置在单个CloudFront分发版后面,则存储桶将接收对一个路径前缀的所有请求,例如/media/*,如果应用程序接收到任何其他路径的请求,并且您的主机名指向CloudFront,那么请求将不再是跨源的,它们将是同一个源,问题就消失了。您需要使用CloudFront签名URL,而不是S3不同的算法,但是您还可以从应用程序用户附近响应的边缘缓存中获益。嘿,您找到了如何从响应头获取“etag”值的解决方案吗?我也面临着同样的问题。最近我使用了MINIO类似的功能,如AWS S3,iirc无法像我最初的问题那样获取ETAG值。