是否可以在不下载整个对象的情况下更改S3对象上的标题?
我已经将一堆图像上传到Amazon S3,现在想要为它们添加一个Cache-Control标头。是否可以在不下载整个对象的情况下更改S3对象上的标题?
无需下载整个图像即可更新标题?如果是这样,怎么样?
它是测试版的功能,但是当您使用copy an object时,您可以指定新的元数据。为副本指定相同的源和目标,并且这只会更新对象上的元数据。
PUT /myObject HTTP/1.1
Host: mybucket.s3.amazonaws.com
x-amz-copy-source: /mybucket/myObject
x-amz-metadata-directive: REPLACE
x-amz-meta-myKey: newValue
不要忘记在headers参数中包含对象的Content-type,因为PUT请求会重写所有原始标题。 – 2011-04-12 11:44:50
通常,复制操作会在源和目标相同时使用您提供的元数据重写所有元数据。请参阅[文档](http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectCOPY.html),了解x-amz-metadata-directive```,它需要相同的拷贝请求目的地来指定```REPLACE```。如果要保留现有用户或S3元数据,则需要获取现有对象的元数据,添加/更改条目并在复制请求中提供更新后的元数据。 – pauljm 2015-04-05 15:04:51
这已经过测试版,可以通过执行put命令并将对象复制为documented here。它也可以在他们的SDK中使用。例如用C#:
var s3Client = new AmazonS3Client("publicKey", "privateKey");
var copyRequest = new CopyObjectRequest()
.WithDirective(S3MetadataDirective.REPLACE)
.WithSourceBucket("bucketName")
.WithSourceKey("fileName")
.WithDestinationBucket("bucketName")
.WithDestinationKey("fileName)
.WithMetaData(new NameValueCollection { { "x-amz-meta-yourKey", "your-value }, { "x-amz-your-otherKey", "your-value" } });
var copyResponse = s3Client.CopyObject(copyRequest);
感谢您的更新。 :) – Scott 2012-01-19 01:09:59
@Scott嗨,得到“试图使用不是或不再可用的对象”。使用新的API – 2014-03-06 13:25:31
与亚马逊AWS-SDK,这样做有额外的头一个copy_object似乎这样的伎俩来设置缓存控制标头为现有S3对象。
===================== x ======================== =======================
<?php
error_reporting(-1);
require_once 'sdk.class.php';
// UPLOAD FILES TO S3
// Instantiate the AmazonS3 class
$options = array("key" => "aws-key" , "secret" => "aws-secret") ;
$s3 = new AmazonS3($options);
$bucket = "bucket.3mik.com" ;
$exists = $s3->if_bucket_exists($bucket);
if(!$exists) {
trigger_error("S3 bucket does not exists \n" , E_USER_ERROR);
}
$name = "cows-and-aliens.jpg" ;
echo " change headers for $name \n" ;
$source = array("bucket" => $bucket, "filename" => $name);
$dest = array("bucket" => $bucket, "filename" => $name);
//caching headers
$offset = 3600*24*365;
$expiresOn = gmdate('D, d M Y H:i:s \G\M\T', time() + $offset);
$headers = array('Expires' => $expiresOn, 'Cache-Control' => 'public, max-age=31536000');
$meta = array('acl' => AmazonS3::ACL_PUBLIC, 'headers' => $headers);
$response = $s3->copy_object($source,$dest,$meta);
if($response->isOk()){
printf("copy object done \n");
}else {
printf("Error in copy object \n");
}
?>
==================== === X ============================================== ==
这是你如何与AWS SDK做了PHP 2:
<?php
require 'vendor/autoload.php';
use Aws\Common\Aws;
use Aws\S3\Enum\CannedAcl;
use Aws\S3\Exception\S3Exception;
const MONTH = 2592000;
// Instantiate an S3 client
$s3 = Aws::factory('config.php')->get('s3');
// Settings
$bucketName = 'example.com';
$objectKey = 'image.jpg';
$maxAge = MONTH;
$contentType = 'image/jpeg';
try {
$o = $s3->copyObject(array(
'Bucket' => $bucketName,
'Key' => $objectKey,
'CopySource' => $bucketName . '/'. $objectKey,
'MetadataDirective' => 'REPLACE',
'ACL' => CannedAcl::PUBLIC_READ,
'command.headers' => array(
'Cache-Control' => 'public,max-age=' . $maxAge,
'Content-Type' => $contentType
)
));
// print_r($o->ETag);
} catch (Exception $e) {
echo $objectKey . ': ' . $e->getMessage() . PHP_EOL;
}
?>
在Java中,试试这个
S3Object s3Object = amazonS3Client.getObject(bucketName, fileKey);
ObjectMetadata metadata = s3Object.getObjectMetadata();
Map customMetaData = new HashMap();
customMetaData.put("yourKey", "updateValue");
customMetaData.put("otherKey", "newValue");
metadata.setUserMetadata(customMetaData);
amazonS3Client.putObject(new PutObjectRequest(bucketName, fileId, s3Object.getObjectContent(), metadata));
您也可以尝试复制对象。这里元数据在复制对象时不会复制。 您必须获取原始的元数据并设置为复制请求。推荐 这种方法更多地插入或亚马逊S3对象
ObjectMetadata metadata = amazonS3Client.getObjectMetadata(bucketName, fileKey);
ObjectMetadata metadataCopy = new ObjectMetadata();
metadataCopy.addUserMetadata("yourKey", "updateValue");
metadataCopy.addUserMetadata("otherKey", "newValue");
metadataCopy.addUserMetadata("existingKey", metadata.getUserMetaDataOf("existingValue"));
CopyObjectRequest request = new CopyObjectRequest(bucketName, fileKey, bucketName, fileKey)
.withSourceBucketName(bucketName)
.withSourceKey(fileKey)
.withNewObjectMetadata(metadataCopy);
amazonS3Client.copyObject(request);
我有同样的需要更新元数据,所以我写了这为我的环境的NodeJS。
https://github.com/newbreedofgeek/s3-bucket-cache-control
我测试过它,但请首先做你的尽职调查作为一个有风险的变化。
以下是Python中的帮助代码。
import boto
one_year = 3600*24*365
cckey = 'cache-control'
s3_connection = S3Connection()
bucket_name = 'my_bucket'
bucket = s3_connection.get_bucket(bucket_name validate=False)
for key in bucket:
key_name = key.key
if key.size == 0: # continue on directories
continue
# Get key object
key = bucket.get_key(key_name)
if key.cache_control is not None:
print("Exists")
continue
cache_time = one_year
#set metdata
key.set_metadata(name=cckey, value = ('max-age=%d, public' % (cache_time)))
key.set_metadata(name='content-type', value = key.content_type)
# Copy the same key
key2 = key.copy(key.bucket.name, key.name, key.metadata, preserve_acl=True)
continue
说明:代码添加新的元数据到现有的密钥,然后复制相同的文件。
x-amz-metadata-directive头不起作用。每次都会导致签名不匹配。所有其他的x-amz头文件工作正常。 – 2010-05-26 15:15:05