使用 rest API 将 blob 从一个存储帐户复制到同一订阅中的另一个存储帐户
Azure copy blobs from one storage account to another in the same subscription using rest API
我想使用 Rest API 和 PHP 将 blob 从一个存储帐户复制到同一订阅中的另一个存储帐户。我可以使用以下代码将 blob 从一个容器复制到同一存储帐户中的另一个容器
<?php
$date = gmdate('D, d M Y H:i:s \G\M\T');
$account_name = "accname";
$destcontainername = "destcontainer";
$blobname = "blob.png";
$sourcecontainer = "sourcecontainer";
$account_key = "asdf";
$canonicalizedHeaders = "x-ms-copy-source:https://".$account_name.".blob.core.windows.net/".$sourcecontainer."/".$blobname."\nx-ms-date:$date\nx-ms-version:2015-04-05";
$canonicalizedResource = "/$account_name/$destcontainername/$blobname";
$arraysign = array();
$arraysign[] = 'PUT'; /*HTTP Verb*/
$arraysign[] = ''; /*Content-Encoding*/
$arraysign[] = ''; /*Content-Language*/
$arraysign[] = ''; /*Content-Length (include value when zero)*/
$arraysign[] = ''; /*Content-MD5*/
$arraysign[] = ''; /*Content-Type*/
$arraysign[] = ''; /*Date*/
$arraysign[] = ''; /*If-Modified-Since */
$arraysign[] = ''; /*If-Match*/
$arraysign[] = ''; /*If-None-Match*/
$arraysign[] = ''; /*If-Unmodified-Since*/
$arraysign[] = ''; /*Range*/
$arraysign[] = $canonicalizedHeaders; /*CanonicalizedHeaders*/
$arraysign[] = $canonicalizedResource; /*CanonicalizedResource*/
$stringtosign = implode("\n", $arraysign);
$signature = 'SharedKey'.' '.$account_name.':'.base64_encode(hash_hmac('sha256', $stringtosign, base64_decode($account_key), true));
$endpoint = 'https://'.$account_name.'.blob.core.windows.net';
$url = $endpoint.'/'.$destcontainername.'/'.$blobname;
$headers = [
'x-ms-copy-source:https://'.$account_name.'.blob.core.windows.net/'.$sourcecontainer.'/'.$blobname,
"x-ms-date:{$date}",
'x-ms-version:2015-04-05',
'Accept:application/json;odata=nometadata',
'Accept-Charset:UTF-8',
'Content-Length:0',
"Authorization:{$signature}"
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
echo curl_error($ch);
curl_close($ch);
echo '<pre>';print_r($response);
我想知道我是否必须使用相同的副本 blob rest API 来完成它。如果是,那么 $canonicalizedHeaders
和 $canonicalizedResource
将是什么,并请求休息 API。我可以使用下面的 powershell 命令将 blob 从一个存储帐户复制到另一个
Start-AzureStorageBlobCopy -DestContainer $destinationContainerName -DestContext $destinationContext -SrcBlob $vhdName -Context $sourceContext -SrcContainer $sourceSAContainerName
您也可以使用相同的代码跨存储帐户复制 blob。虽然 $canonicalizedResource
保持不变,但您需要将源 blob 的 URL 包含在 x-ms-copy-source
header 中 $canonicalizedHeaders
.
要牢记的一件重要事情是,您在 x-ms-copy-source
header 中指定的源 blob URL 必须可公开访问。这意味着如果您将 URL 粘贴到浏览器的地址栏中,您应该能够访问该 blob。如果源 blob 容器的 ACL 是 Blob
或 Container
,那么您可以简单地指定 blob URL (https://sourceaccountname.blob.core.windows.net/sourceblobcontainer/sourceblobname
) 但是如果源 blob 容器的 ACL 是 Private
那么您需要在至少具有 Read
权限的源 blob 上创建一个 Shared Access Signature (SAS)
,并为此 header 的值使用 SAS URL。
另一件需要理解的事情是,跨存储帐户复制是一个异步操作。因此,当上面的代码成功执行时,blob 复制操作就会排队。在删除源 blob 或对其进行任何更改之前,您必须检查复制操作是否已完成,否则复制操作将失败。
我想使用 Rest API 和 PHP 将 blob 从一个存储帐户复制到同一订阅中的另一个存储帐户。我可以使用以下代码将 blob 从一个容器复制到同一存储帐户中的另一个容器
<?php
$date = gmdate('D, d M Y H:i:s \G\M\T');
$account_name = "accname";
$destcontainername = "destcontainer";
$blobname = "blob.png";
$sourcecontainer = "sourcecontainer";
$account_key = "asdf";
$canonicalizedHeaders = "x-ms-copy-source:https://".$account_name.".blob.core.windows.net/".$sourcecontainer."/".$blobname."\nx-ms-date:$date\nx-ms-version:2015-04-05";
$canonicalizedResource = "/$account_name/$destcontainername/$blobname";
$arraysign = array();
$arraysign[] = 'PUT'; /*HTTP Verb*/
$arraysign[] = ''; /*Content-Encoding*/
$arraysign[] = ''; /*Content-Language*/
$arraysign[] = ''; /*Content-Length (include value when zero)*/
$arraysign[] = ''; /*Content-MD5*/
$arraysign[] = ''; /*Content-Type*/
$arraysign[] = ''; /*Date*/
$arraysign[] = ''; /*If-Modified-Since */
$arraysign[] = ''; /*If-Match*/
$arraysign[] = ''; /*If-None-Match*/
$arraysign[] = ''; /*If-Unmodified-Since*/
$arraysign[] = ''; /*Range*/
$arraysign[] = $canonicalizedHeaders; /*CanonicalizedHeaders*/
$arraysign[] = $canonicalizedResource; /*CanonicalizedResource*/
$stringtosign = implode("\n", $arraysign);
$signature = 'SharedKey'.' '.$account_name.':'.base64_encode(hash_hmac('sha256', $stringtosign, base64_decode($account_key), true));
$endpoint = 'https://'.$account_name.'.blob.core.windows.net';
$url = $endpoint.'/'.$destcontainername.'/'.$blobname;
$headers = [
'x-ms-copy-source:https://'.$account_name.'.blob.core.windows.net/'.$sourcecontainer.'/'.$blobname,
"x-ms-date:{$date}",
'x-ms-version:2015-04-05',
'Accept:application/json;odata=nometadata',
'Accept-Charset:UTF-8',
'Content-Length:0',
"Authorization:{$signature}"
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
echo curl_error($ch);
curl_close($ch);
echo '<pre>';print_r($response);
我想知道我是否必须使用相同的副本 blob rest API 来完成它。如果是,那么 $canonicalizedHeaders
和 $canonicalizedResource
将是什么,并请求休息 API。我可以使用下面的 powershell 命令将 blob 从一个存储帐户复制到另一个
Start-AzureStorageBlobCopy -DestContainer $destinationContainerName -DestContext $destinationContext -SrcBlob $vhdName -Context $sourceContext -SrcContainer $sourceSAContainerName
您也可以使用相同的代码跨存储帐户复制 blob。虽然 $canonicalizedResource
保持不变,但您需要将源 blob 的 URL 包含在 x-ms-copy-source
header 中 $canonicalizedHeaders
.
要牢记的一件重要事情是,您在 x-ms-copy-source
header 中指定的源 blob URL 必须可公开访问。这意味着如果您将 URL 粘贴到浏览器的地址栏中,您应该能够访问该 blob。如果源 blob 容器的 ACL 是 Blob
或 Container
,那么您可以简单地指定 blob URL (https://sourceaccountname.blob.core.windows.net/sourceblobcontainer/sourceblobname
) 但是如果源 blob 容器的 ACL 是 Private
那么您需要在至少具有 Read
权限的源 blob 上创建一个 Shared Access Signature (SAS)
,并为此 header 的值使用 SAS URL。
另一件需要理解的事情是,跨存储帐户复制是一个异步操作。因此,当上面的代码成功执行时,blob 复制操作就会排队。在删除源 blob 或对其进行任何更改之前,您必须检查复制操作是否已完成,否则复制操作将失败。