本文中含有需要您注意的重要提示信息,忽略该信息可能对您的业务造成影响,请务必仔细阅读。
默认情况下,OSS存储空间中文件的读写权限是私有,仅文件拥有者可以访问。但文件拥有者可以对指定文件生成具有临时访问权限的签名URL,以允许他人使用该签名URL在有效期内下载文件。
什么是签名URL
签名URL是一种由客户端基于本地密钥信息生成的临时授权访问链接,可允许第三方在有效期内下载或预览私有文件,而无需暴露访问密钥。签名URL的格式为https://BucketName.Endpoint/Object?签名参数
。
在以下场景下,建议您选择签名URL来满足文件下载需求:
短期文件共享:第三方申请下载指定文件,后端便生成带有效期的签名URL并返回给前端,确保文件在指定时间内可下载,保障数据安全
灵活访问:通过邮件或聊天工具分享URL,无需复杂认证,第三方获取URL后在浏览器地址栏粘贴即可下载文件。
注意事项
本文以华东1(杭州)外网Endpoint为例。如果您希望通过与OSS同地域的其他阿里云产品访问OSS,请使用内网Endpoint。关于OSS支持的Region与Endpoint的对应关系,请参见OSS地域和访问域名。
生成GET方法的签名URL时,您必须具有
oss:GetObject
权限。具体操作,请参见RAM Policy常见示例。说明生成签名URL过程中,SDK利用本地存储的密钥信息,根据特定算法计算出签名(signature),然后将其附加到URL上,以确保URL的有效性和安全性。这一系列计算和构造URL的操作都是在客户端完成,不涉及网络请求到服务端。因此,生成签名URL时不需要授予调用者特定权限。但是,为避免第三方用户无法对签名URL授权的资源执行相关操作,需要确保调用生成签名URL接口的身份主体被授予对应的权限。
签名URL在有效期内可多次访问,超期后,需执行步骤一重新生成签名URL以继续访问文件。
流程概览
使用签名URL下载文件的过程如下:
详细步骤
步骤一:文件拥有者生成GET方法的签名URL
通过OSS控制台和ossbrowser生成的签名URL,最大有效时长为32400秒(9 小时)。
通过命令行工具ossutil和SDK生成的签名URL,最大有效时长为7天。
若使用STSToken来生成签名URL,则最大有效时长为43200秒(12小时)。
使用OSS控制台
您可以通过OSS控制台生成文件的签名URL。
登录OSS管理控制台。
单击Bucket列表,然后单击目标Bucket名称。
在左侧导航栏,选择
。获取文件URL。
单击目标文件名称。
在详情面板配置以下参数,然后单击复制文件 URL。
参数
说明
过期时间
当目标文件为私有文件时,需设置文件URL的有效时间。
取值范围:60~32400
单位:秒
如果您希望设置更长过期时间的文件URL,您可以使用sdk、ossutil等工具。
自有域名
如需确保第三方访问图片或网页文件时是预览行为,请使用Bucket绑定的自定义域名生成文件URL。
仅当Bucket绑定自定义域名后可配置此项。更多信息,请参见绑定自定义域名。
使用HTTPS
默认使用HTTPS协议生成签名URL。如需使用HTTP协议生成文件URL,请关闭使用HTTPS开关。
使用图形化管理工具ossbrowser
安装ossbrowser 2.0,如已完成安装,请忽略此步骤。
登录ossbrowser 2.0,如已完成登录,请忽略此步骤。
单击目标Bucket名称,找到目标Object。
方式一:单击目标Object名称,然后在弹窗右下角单击“复制”获取签名URL。该方式生成默认3600秒有效期的签名URL。
方式二:自定义签名URL有效期。
单击目标Object的
,然后单击获取地址
修改签名URL有效期,范围为60到32400秒。
单击复制地址即可获取签名URL。
更多ossbrowser用法,请参见图形化管理工具ossbrowser 2.0。
使用阿里云SDK
本文以OSS域名新建OSSClient为例。如果您希望通过自定义域名、STS等方式新建OSSClient,请参见配置客户端。
以下仅列举常见语言的生成签名URL的代码示例。
Java
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import java.net.URL;
import java.util.Date;
public class Demo {
public static void main(String[] args) throws Throwable {
// 以华东1(杭州)的外网Endpoint为例,其它Region请按实际情况填写。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// 填写Bucket名称,例如examplebucket。
String bucketName = "examplebucket";
// 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。
String objectName = "exampleobject.txt";
// 填写Bucket所在地域。以华东1(杭州)为例,Region填写为cn-hangzhou。
String region = "cn-hangzhou";
// 创建OSSClient实例。
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
OSS ossClient = OSSClientBuilder.create()
.endpoint(endpoint)
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region(region)
.build();
try {
// 设置签名URL过期时间,单位为毫秒。本示例以设置过期时间为1小时为例。
Date expiration = new Date(new Date().getTime() + 3600 * 1000L);
// 生成以GET方法访问的签名URL。本示例没有额外请求头,其他人可以直接通过浏览器访问相关内容。
URL url = ossClient.generatePresignedUrl(bucketName, objectName, expiration);
System.out.println(url);
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}
Python
# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
# 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())
# 填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
# 填写Endpoint对应的Region信息,例如cn-hangzhou。注意,v4签名下,必须填写该参数
region = "cn-hangzhou"
# yourBucketName填写存储空间名称。
bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region)
# 填写Object完整路径,例如exampledir/exampleobject.txt。Object完整路径中不能包含Bucket名称。
object_name = 'exampledir/exampleobject.txt'
# 生成下载文件的签名URL,有效时间为600秒。
# 生成签名URL时,OSS默认会对Object完整路径中的正斜线(/)进行转义,从而导致生成的签名URL无法直接使用。
# 设置slash_safe为True,OSS不会对Object完整路径中的正斜线(/)进行转义,此时生成的签名URL可以直接使用。
url = bucket.sign_url('GET', object_name, 600, slash_safe=True)
print('签名URL的地址为:', url)
Go
package main
import (
"context"
"flag"
"log"
"time"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)
// 定义全局变量
var (
region string // 存储区域
bucketName string // 存储空间名称
objectName string // 对象名称
)
// init函数用于初始化命令行参数
func init() {
flag.StringVar(®ion, "region", "", "The region in which the bucket is located.")
flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
flag.StringVar(&objectName, "object", "", "The name of the object.")
}
func main() {
// 解析命令行参数
flag.Parse()
// 检查bucket名称是否为空
if len(bucketName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, bucket name required")
}
// 检查region是否为空
if len(region) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, region required")
}
// 检查object名称是否为空
if len(objectName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, object name required")
}
// 加载默认配置并设置凭证提供者和区域
cfg := oss.LoadDefaultConfig().
WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
WithRegion(region)
// 创建OSS客户端
client := oss.NewClient(cfg)
// 生成GetObject的预签名URL
result, err := client.Presign(context.TODO(), &oss.GetObjectRequest{
Bucket: oss.Ptr(bucketName),
Key: oss.Ptr(objectName),
},
oss.PresignExpires(10*time.Minute),
)
if err != nil {
log.Fatalf("failed to get object presign %v", err)
}
log.Printf("request method:%v\n", result.Method)
log.Printf("request expiration:%v\n", result.Expiration)
log.Printf("request url:%v\n", result.URL)
if len(result.SignedHeaders) > 0 {
//当返回结果包含签名头时,使用签名URL发送GET请求时也包含相应的请求头,以免出现不一致,导致请求失败和签名错误
log.Printf("signed headers:\n")
for k, v := range result.SignedHeaders {
log.Printf("%v: %v\n", k, v)
}
}
}
Node.js
const OSS = require("ali-oss");
// 定义一个生成签名 URL 的函数
async function generateSignatureUrl(fileName) {
// 获取签名URL
const client = await new OSS({
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
accessKeyId: process.env.OSS_ACCESS_KEY_ID,
accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
bucket: 'examplebucket',
// yourregion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
region: 'oss-cn-hangzhou',
// 设置secure为true,使用HTTPS,避免生成的下载链接被浏览器拦截
secure: true,
authorizationV4: true
});
return await client.signatureUrlV4('GET', 3600, {
headers: {} // 请根据实际发送的请求头设置此处的请求头
}, fileName);
}
// 调用函数并传入文件名
generateSignatureUrl('yourFileName').then(url => {
console.log('Generated Signature URL:', url);
}).catch(err => {
console.error('Error generating signature URL:', err);
});
PHP
<?php
if (is_file(__DIR__ . '/../autoload.php')) {
require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
require_once __DIR__ . '/../vendor/autoload.php';
}
use OSS\OssClient;
use OSS\Core\OssException;
use OSS\Http\RequestCore;
use OSS\Http\ResponseCore;
use OSS\Credentials\EnvironmentVariableCredentialsProvider;
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
$provider = new EnvironmentVariableCredentialsProvider();
// yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
$endpoint = "yourEndpoint";
// 填写Bucket名称。
$bucket= "examplebucket";
// 填写不包含Bucket名称在内的Object完整路径。
$object = "exampleobject.txt";
// 指定签名URL的过期时间为600s(最长可达32400s)。
$timeout = 600;
try {
$config = array(
"provider" => $provider,
"endpoint" => $endpoint,
'signatureVersion'=>OssClient::OSS_SIGNATURE_VERSION_V4,
"region"=> "cn-hangzhou"
);
$ossClient = new OssClient($config);
// 生成签名URL。
$signedUrl = $ossClient->signUrl($bucket, $object, $timeout, "GET");
print_r($signedUrl);
} catch (OssException $e) {
printf(__FUNCTION__ . ": FAILED\n");
printf($e->getMessage() . "\n");
return;
}
.NET
using Aliyun.OSS;
using Aliyun.OSS.Common;
// 填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
var endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID");
var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET");
// 填写Bucket名称,例如examplebucket。
var bucketName = "examplebucket";
// 填写Object完整路径,完整路径中不包含Bucket名称,例如exampledir/exampleobject.txt。
var objectName = "exampledir/exampleobject.txt";
var objectContent = "More than just cloud.";
// 创建OSSClient实例。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
try
{
// 生成签名URL。
var generatePresignedUriRequest = new GeneratePresignedUriRequest(bucketName, objectName, SignHttpMethod.Put)
{
// 设置签名URL过期时间,默认值为3600秒。
Expiration = DateTime.Now.AddHours(1),
};
var signedUrl = client.GeneratePresignedUri(generatePresignedUriRequest);
}
catch (OssException ex)
{
Console.WriteLine("Failed with error code: {0}; Error info: {1}. \nRequestID:{2}\tHostID:{3}",
ex.ErrorCode, ex.Message, ex.RequestId, ex.HostId);
}
catch (Exception ex)
{
Console.WriteLine("Failed with error info: {0}", ex.Message);
}
Android
// 填写Bucket名称,例如examplebucket。
String bucketName = "examplebucket";
// 填写不包含Bucket名称在内源Object的完整路径,例如exampleobject.txt。
String objectKey = "exampleobject.txt";
String url = null;
try {
// 生成用于下载文件的签名URL。
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectKey);
// 设置签名URL的过期时间为30分钟。
request.setExpiration(30*60);
request.setMethod(HttpMethod.GET);
url = oss.presignConstrainedObjectURL(request);
Log.d("url", url);
} catch (ClientException e) {
e.printStackTrace();
}
iOS
// 填写Bucket名称。
NSString *bucketName = @"examplebucket";
// 填写Object名称。
NSString *objectKey = @"exampleobject.txt";
__block NSString *urlString;
// 生成用于下载的签名URL,并指定签名URL过期时间为30分钟。
OSSTask *task = [client presignConstrainURLWithBucketName:bucketName
withObjectKey:objectKey
httpMethod:@"GET"
withExpirationInterval:30 * 60
withParameters:@{}];
[task continueWithBlock:^id _Nullable(OSSTask * _Nonnull task) {
if (task.error) {
NSLog(@"presign error: %@", task.error);
} else {
urlString = task.result;
NSLog(@"url: %@", urlString);
}
return nil;
}];
C++
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;
int main(void)
{
/* 初始化OSS账号信息。*/
/* yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。*/
std::string Endpoint = "yourEndpoint";
/ *yourRegion填写Bucket所在地域对应的Region。以华东1(杭州)为例,Region填写为cn - hangzhou。 * /
std::string Region = "yourRegion";
/* 填写Bucket名称,例如examplebucket。*/
std::string BucketName = "examplebucket";
/* 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。*/
std::string GetobjectUrlName = "exampledir/exampleobject.txt";
/* 初始化网络等资源。*/
InitializeSdk();
ClientConfiguration conf;
conf.signatureVersion = SignatureVersionType::V4;
/* 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/
auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
OssClient client(Endpoint, credentialsProvider, conf);
client.SetRegion(Region);
/* 设置签名有效时长,最大有效时间为32400秒。*/
std::time_t t = std::time(nullptr) + 1200;
/* 生成签名URL。*/
auto genOutcome = client.GeneratePresignedUrl(BucketName, GetobjectUrlName, t, Http::Get);
if (genOutcome.isSuccess()) {
std::cout << "GeneratePresignedUrl success, Gen url:" << genOutcome.result().c_str() << std::endl;
}
else {
/* 异常处理。*/
std::cout << "GeneratePresignedUrl fail" <<
",code:" << genOutcome.error().Code() <<
",message:" << genOutcome.error().Message() <<
",requestId:" << genOutcome.error().RequestId() << std::endl;
return -1;
}
/* 释放网络等资源。*/
ShutdownSdk();
return 0;
}
Ruby
require 'aliyun/oss'
client = Aliyun::OSS::Client.new(
# Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
endpoint: 'https://oss-cn-hangzhou.aliyuncs.com',
# 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
access_key_id: ENV['OSS_ACCESS_KEY_ID'],
access_key_secret: ENV['OSS_ACCESS_KEY_SECRET']
)
# 填写Bucket名称,例如examplebucket。
bucket = client.get_bucket('examplebucket')
# 生成签名URL,并指定URL有效时间为1小时(3600秒)。
puts bucket.object_url('my-object', true, 3600)
C
#include "oss_api.h"
#include "aos_http_io.h"
/* yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。*/
const char *endpoint = "yourEndpoint";
/* 填写Bucket名称,例如examplebucket。*/
const char *bucket_name = "examplebucket";
/* 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。*/
const char *object_name = "exampledir/exampleobject.txt";
/* 填写本地文件的完整路径。*/
const char *local_filename = "yourLocalFilename";
void init_options(oss_request_options_t *options)
{
options->config = oss_config_create(options->pool);
/* 用char*类型的字符串初始化aos_string_t类型。*/
aos_str_set(&options->config->endpoint, endpoint);
/* 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/
aos_str_set(&options->config->access_key_id, getenv("OSS_ACCESS_KEY_ID"));
aos_str_set(&options->config->access_key_secret, getenv("OSS_ACCESS_KEY_SECRET"));
/* 是否使用CNAME访问OSS服务。0表示不使用。*/
options->config->is_cname = 0;
/* 设置网络相关参数,例如超时时间等。*/
options->ctl = aos_http_controller_create(options->pool, 0);
}
int main(int argc, char *argv[])
{
/* 在程序入口调用aos_http_io_initialize方法来初始化网络、内存等全局资源。*/
if (aos_http_io_initialize(NULL, 0) != AOSE_OK) {
exit(1);
}
/* 用于内存管理的内存池(pool),等价于apr_pool_t。其实现代码在apr库中。*/
aos_pool_t *pool;
/* 重新创建一个内存池,第二个参数是NULL,表示没有继承其它内存池。*/
aos_pool_create(&pool, NULL);
/* 创建并初始化options,该参数包括endpoint、access_key_id、acces_key_secret、is_cname、curl等全局配置信息。*/
oss_request_options_t *oss_client_options;
/* 在内存池中分配内存给options。*/
oss_client_options = oss_request_options_create(pool);
/* 初始化Client的选项oss_client_options。*/
init_options(oss_client_options);
/* 初始化参数。*/
aos_string_t bucket;
aos_string_t object;
aos_string_t file;
aos_http_request_t *req;
apr_time_t now;
char *url_str;
aos_string_t url;
int64_t expire_time;
int one_hour = 3600;
aos_str_set(&bucket, bucket_name);
aos_str_set(&object, object_name);
aos_str_set(&file, local_filename);
expire_time = now / 1000000 + one_hour;
req = aos_http_request_create(pool);
req->method = HTTP_GET;
now = apr_time_now();
/* 单位:微秒 */
expire_time = now / 1000000 + one_hour;
/* 生成签名URL。*/
url_str = oss_gen_signed_url(oss_client_options, &bucket, &object, expire_time, req);
aos_str_set(&url, url_str);
printf("临时下载URL: %s\n", url_str);
/* 释放内存池,相当于释放了请求过程中各资源分配的内存。*/
aos_pool_destroy(pool);
/* 释放之前分配的全局资源。*/
aos_http_io_deinitialize();
return 0;
}
生成的URL示例如下:
https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-process=image%2Fresize%2Cp_10&x-oss-date=20241115T095058Z&x-oss-expires=3600&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI***********1Uuu%2F20241115%2Fcn-hangzhou%2Foss%2Faliyun_v4_request&x-oss-signature=6e7*************************1eb79d96
使用命令行工具ossutil
对存储空间examplebucket里的example.txt对象,生成默认有效期为15分钟的预签名URL,命令如下。
ossutil presign oss://examplebucket/example.txt
关于使用ossutil生成签名URL的具体操作, 请参见presign(生成预签名URL)。
步骤二:其他人使用GET方法的签名URL下载文件
使用浏览器下载
复制步骤一生成的URL并粘贴到浏览器地址栏,按回车键即可下载文件。
使用curl命令下载
在终端输入以下命令,将 <signed_url> 替换为步骤一生成的签名 URL。
curl -SO "<signed_url>"
命令示例:
curl -SO "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI5************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a939feb8d79a389572719f7e2939939936d0**********"
使用wget命令下载
在终端输入以下命令,将<signed_url>替换为步骤一生成的签名 URL,文件将以自定义文件名 example.txt保存在当前目录中。
wget -O example.txt "<signed_url>"
命令示例:
wget -O example.txt "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI5************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a939feb8d79a389572719f7e2939939936d0**********"
使用阿里云SDK下载
Java
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class Demo {
public static void main(String[] args) {
// 替换为生成的GET方法的签名URL。
String fileURL = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI5************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a939feb8d79a389572719f7e2939939936d0**********";
// 填写文件保存的目标路径,包括文件名和扩展名。
String savePath = "C:/downloads/myfile.txt";
try {
downloadFile(fileURL, savePath);
System.out.println("Download completed!");
} catch (IOException e) {
System.err.println("Error during download: " + e.getMessage());
}
}
private static void downloadFile(String fileURL, String savePath) throws IOException {
URL url = new URL(fileURL);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
httpConn.setRequestMethod("GET");
// 检查响应代码
int responseCode = httpConn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
// 输入流
InputStream inputStream = new BufferedInputStream(httpConn.getInputStream());
// 输出流
FileOutputStream outputStream = new FileOutputStream(savePath);
byte[] buffer = new byte[4096]; // 缓冲区
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
inputStream.close();
} else {
System.out.println("No file to download. Server replied HTTP code: " + responseCode);
}
httpConn.disconnect();
}
}
Python
import requests
file_url = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI5************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a939feb8d79a389572719f7e2939939936d0**********"
save_path = "C:/downloads/myfile.txt"
try:
response = requests.get(file_url, stream=True)
if response.status_code == 200:
with open(save_path, 'wb') as f:
for chunk in response.iter_content(4096):
f.write(chunk)
print("Download completed!")
else:
print(f"No file to download. Server replied HTTP code: {response.status_code}")
except Exception as e:
print("Error during download:", e)
Go
package main
import (
"io"
"net/http"
"os"
)
func main() {
fileURL := "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI5************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a939feb8d79a389572719f7e2939939936d0**********"
savePath := "C:/downloads/myfile.txt"
response, err := http.Get(fileURL)
if err != nil {
panic(err)
}
defer response.Body.Close()
if response.StatusCode == http.StatusOK {
outFile, err := os.Create(savePath)
if err != nil {
panic(err)
}
defer outFile.Close()
_, err = io.Copy(outFile, response.Body)
if err != nil {
panic(err)
}
println("Download completed!")
} else {
println("No file to download. Server replied HTTP code:", response.StatusCode)
}
}
Node.js
const https = require('https');
const fs = require('fs');
const fileURL = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI5************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a939feb8d79a389572719f7e2939939936d0**********";
const savePath = "C:/downloads/myfile.txt";
https.get(fileURL, (response) => {
if (response.statusCode === 200) {
const fileStream = fs.createWriteStream(savePath);
response.pipe(fileStream);
fileStream.on('finish', () => {
fileStream.close();
console.log("Download completed!");
});
} else {
console.error(`Download failed. Server responded with code: ${response.statusCode}`);
}
}).on('error', (err) => {
console.error("Error during download:", err.message);
});
browser.js
const fileURL = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI5************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a939feb8d79a389572719f7e2939939936d0**********";
const savePath = "C:/downloads/myfile.txt"; // 文件将在下载时使用的文件名
fetch(fileURL)
.then(response => {
if (!response.ok) {
throw new Error(`Server replied HTTP code: ${response.status}`);
}
return response.blob(); // 将响应转换为 blob
})
.then(blob => {
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = savePath; // 设置下载文件的名字
document.body.appendChild(link); // 此步骤确保链接存在于文档中
link.click(); // 模拟点击下载链接
link.remove(); // 完成后移除链接
console.log("Download completed!");
})
.catch(error => {
console.error("Error during download:", error);
});
Android
import android.os.AsyncTask;
import android.os.Environment;
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class DownloadTask extends AsyncTask<String, String, String> {
@Override
protected String doInBackground(String... params) {
String fileURL = params[0];
String savePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/myfile.txt"; // 修改后的保存路径
try {
URL url = new URL(fileURL);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
httpConn.setRequestMethod("GET");
int responseCode = httpConn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream inputStream = new BufferedInputStream(httpConn.getInputStream());
FileOutputStream outputStream = new FileOutputStream(savePath);
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
inputStream.close();
return "Download completed!";
} else {
return "No file to download. Server replied HTTP code: " + responseCode;
}
} catch (Exception e) {
return "Error during download: " + e.getMessage();
}
}
}
iOS
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
// 定义文件 URL 和保存路径(修改为有效的路径)
NSString *fileURL = @"https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI5************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a939feb8d79a389572719f7e2939939936d0**********";
NSString *savePath = @"/Users/your_username/Desktop/myfile.txt"; // 请替换为您的用户名
// 创建 URL 对象
NSURL *url = [NSURL URLWithString:fileURL];
// 创建下载任务
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// 错误处理
if (error) {
NSLog(@"Error during download: %@", error.localizedDescription);
return;
}
// 检查数据
if (!data) {
NSLog(@"No data received.");
return;
}
// 保存文件
NSError *writeError = nil;
BOOL success = [data writeToURL:[NSURL fileURLWithPath:savePath] options:NSDataWritingAtomic error:&writeError];
if (success) {
NSLog(@"Download completed!");
} else {
NSLog(@"Error saving file: %@", writeError.localizedDescription);
}
}];
// 启动任务
[task resume];
// 让主线程继续运行以便异步请求能够完成
[[NSRunLoop currentRunLoop] run];
}
return 0;
}