全部产品
Search
文档中心

对象存储 OSS:开启请求者付费模式让请求者支付流量、请求次数、数据处理费用

更新时间:Apr 18, 2024

通常情况下,存储空间(Bucket)的拥有者需要支付Bucket产生的所有费用。然而,您可以为Bucket开启请求者付费模式,使通过身份验证的请求者支付访问Bucket内数据时产生的流量、请求次数、数据处理费用,而Bucket的拥有者仅支付存储等其他费用。当您希望共享数据,但又不希望支付因共享数据产生的额外费用时,您可以开启请求者付费模式。

使用场景

  • 共享大型数据集。例如某研究机构希望所有客户都能访问包含邮政编码目录、参考数据、地理空间信息或网络爬取等数据的共享数据集,同时希望下载数据产生的流量费用和请求次数费用需由请求者支付。

    配置步骤如下:

    1. 确保共享数据集所属Bucket的读写权限ACL为公共读。具体操作,请参见设置Bucket ACL

    2. 为该Bucket开启请求者付费模式。

  • 将生产数据交付给您的客户或合作伙伴。例如,某公司需要将生产数据交付给该公司的合作伙伴,下载数据产生的流量费用和请求次数费用需要由合作伙伴支付。

    配置步骤如下:

    1. 确保生产数据所属Bucket的读写权限ACL为私有。具体操作,请参见设置Bucket ACL

    2. 为该Bucket开启请求者付费模式。

    3. 通过Bucket Policy授权您的合作伙伴访问该Bucket内指定的生产数据。具体操作,请参见基于Bucket Policy实现跨账号访问OSS

    重要

    您需要将Bucket授权给合作伙伴的RAM用户,而不是将您账号下RAM用户的AccessKey提供给合作伙伴进行访问。原因是当合作伙伴通过您账号下的RAM用户访问时,请求者是您自身,请求费用仍需要您(请求者)来支付。

请求方式

  • 不允许匿名访问

    如果您在Bucket上启用了请求者付费模式,则不允许匿名访问该Bucket。请求方必须提供身份验证信息,以便OSS能够识别请求方,从而对请求方而非Bucket拥有者收取请求所产生的费用。

    当请求者是通过扮演阿里云RAM角色来请求数据时,该角色所属的账户将为此请求付费。

  • 请求中需携带请求头x-oss-request-payer

    如果您在Bucket上启用了请求者付费模式,请求中必须携带x-oss-request-payer请求头,且取值为requester,以表明请求方已了解需要支付请求和数据下载费用。否则,请求方无法通过验证。

    • 对于POST、GET和HEAD请求,需在请求中包含x-oss-request-payer:requester信息。详情请参见签名版本4(推荐)

    • 对于签名URL,需在请求中包含x-oss-request-payer=requester信息。详情请参见签名版本4(推荐)

    数据拥有者访问该Bucket时,可以不携带x-oss-request-payer请求头。当数据拥有者作为请求者访问该Bucket时,请求产生的费用由数据拥有者(也是请求者)来支付。

费用说明

Bucket开启请求者付费前,所有费用均由Bucket拥有者支付。Bucket开启请求者付费模式后,由Bucket拥有者支付的计费项将产生变化。Bucket拥有者以及请求者支付的详细说明如下:

费用

计费项

支付者

存储费用

标准存储(本地冗余)容量

Bucket拥有者

标准存储(同城冗余)容量

Bucket拥有者

低频访问(本地冗余)容量

Bucket拥有者

低频访问(同城冗余)容量

Bucket拥有者

归档(本地冗余)容量

Bucket拥有者

归档(同城冗余)容量

Bucket拥有者

冷归档(本地冗余)容量

Bucket拥有者

深度冷归档(本地冗余)容量

Bucket拥有者

低频访问(本地冗余)不足规定时长容量

Bucket拥有者

归档存储(本地冗余)不足规定时长容量

Bucket拥有者

归档存储(同城冗余)不足规定时长容量

Bucket拥有者

冷归档存储不足规定时长容量

Bucket拥有者

深度冷归档存储不足规定时长容量

Bucket拥有者

流量费用

外网流出流量

请求者

外网流入流量

免费

内网流出流量

免费

内网流入流量

免费

CDN回源流出流量

请求者

跨区域复制流量

Bucket拥有者

请求费用

Put类型请求次数

请求者

Get类型请求次数

请求者

取回请求

Bucket拥有者

Select扫描数据量

Bucket拥有者

低频访问数据取回容量

请求者

归档存储数据取回容量

请求者

归档直读数据取回容量

Bucket拥有者

冷归档存储数据取回容量

Bucket拥有者

深度冷归档存储数据取回容量

Bucket拥有者

对象标签费用

对象标签

Bucket拥有者

传输加速费用

传输加速AccM2MIn

Bucket拥有者

传输加速AccM2MOut

Bucket拥有者

传输加速AccM2OIn

Bucket拥有者

传输加速AccM2OOut

Bucket拥有者

传输加速AccO2MIn

Bucket拥有者

传输加速AccO2MOut

Bucket拥有者

传输加速AccO2OIn

Bucket拥有者

传输加速AccO2OOut

Bucket拥有者

临时存储费用

临时存储容量(本地冗余)

Bucket拥有者

DDoS防护费用

高防资源预留费用

Bucket拥有者

高防资源提前释放费用

Bucket拥有者

高防流量防护费用

Bucket拥有者

高防请求防护费用

Bucket拥有者

数据索引费用

Meta管理费

公测阶段,免费

Bucket查询费

公测阶段,免费

说明

如果请求者未在请求中(GET、HEAD或POST)声明请求者付费的请求头x-oss-request-payer,则由Bucket拥有者支付Put类和Get类请求次数费用。

操作步骤

使用OSS控制台

  1. 登录OSS管理控制台

  2. 单击Bucket 列表,然后单击目标Bucket名称。

  3. 在左侧导航栏,选择Bucket 配置 > 请求者付费

  4. 请求者付费页面,打开请求者付费开关。

  5. 在弹出的对话框,单击确定

    说明

    如果您需要关闭请求者付费,您可以关闭请求者付费开关,然后单击确定

使用阿里云SDK

以下仅列举常见SDK的设置请求者付费模式的代码示例。关于其他SDK的设置请求者付费模式的代码示例,请参见SDK简介

import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.*;

public class Demo {
    public static void main(String[] args) throws Exception{
        // Endpoint以华东1(杭州)为例,其它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";

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
        try {
            // 设置请求者付费模式。
            Payer payer = Payer.Requester;
            ossClient.setBucketRequestPayment(bucketName, payer);
        } 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 (Throwable 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 {
            // 关闭OSSClient。
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}
<?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\Credentials\EnvironmentVariableCredentialsProvider;
use OSS\OssClient;
use OSS\Core\OssException;

// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
$provider = new EnvironmentVariableCredentialsProvider();
// Endpoint以杭州为例,其它Region请按实际情况填写。
$endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
// 填写Bucket名称,例如examplebucket。
$bucket= "examplebucket";

try {
    $config = array(
        "provider" => $provider,
        "endpoint" => $endpoint,
    );
    $ossClient = new OssClient($config);
    $ossClient->putBucketRequestPayment($bucket, "Requester");
} catch (OssException $e) {
    printf(__FUNCTION__ . ": FAILED\n");
    printf($e->getMessage() . "\n");
    return;
}

print(__FUNCTION__ . ": OK" . "\n");
const OSS = require('ali-oss')

const client = new OSS({
  // yourregion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
  region: 'yourregion',
  // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
  accessKeyId: process.env.OSS_ACCESS_KEY_ID,
  accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET
});

async function setBucketRequestPayment(bucket, Payer) {
  try {
    // bucket填写需要设置请求者付费模式的存储空间名称。
    // Payer取值为Requester或BucketOwner。
    // Payer设置为Requester,表明该存储空间已开启请求者付费模式,由请求者支付读取存储空间(Bucket)内数据时产生的流量费用和请求费用。
    // Payer设置为BucketOwner,表明该存储空间不开启请求者付费模式(默认状态),即请求产生的费用由数据拥有者(BucketOwner)来支付。
    const result = await client.putBucketRequestPayment(bucket, Payer);
    console.log(result);
  } catch (e) {
    console.log(e);
  }
}

setBucketRequestPayment('bucketName', 'Requester')
# -*- coding: utf-8 -*-

import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
from oss2.models import PAYER_BUCKETOWNER, PAYER_REQUESTER

# 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
# yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
# 填写Bucket名称,例如examplebucket。
bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'examplebucket')

# 设置请求者付费模式,默认的付费者为PAYER_BUCKETOWNER。
result = bucket.put_bucket_request_payment(PAYER_REQUESTER)

print("http respon status: ", result.status)
using Aliyun.OSS;
using Aliyun.OSS.Common;

// yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
var endpoint = "yourEndpoint";
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量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名称。
var bucketName = "examplebucket";

// 创建OSSClient实例。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
try
{
    // 设置请求者付费模式。
    var request = new SetBucketRequestPaymentRequest(bucketName, RequestPayer.Requester);
    client.SetBucketRequestPayment(request);
    Console.WriteLine("Set bucket:{0} RequestPayment succeeded ", bucketName);
}
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);
}
package main

import (
	"fmt"
	"os"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
	// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
	provider, err := oss.NewEnvironmentVariableCredentialsProvider()
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}
	// 创建OSSClient实例。
	// yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
	client, err := oss.New("yourEndpoint", "", "", oss.SetCredentialsProvider(&provider))
	if err != nil {
		fmt.Println("New Error:", err)
		os.Exit(-1)
	}

	// 初始化请求者付费模式。
	reqPayConf := oss.RequestPaymentConfiguration{
		Payer: "Requester",
	}

	// 设置请求者付费模式。
	err = client.SetBucketRequestPayment("<yourBucketName>", reqPayConf)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}
}
#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";
    /*填写Bucket名称,例如examplebucket。*/
    std::string BucketName = "examplebucket";

    /*初始化网络等资源。*/
    InitializeSdk();

    ClientConfiguration conf;
    /* 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);

    /*设置请求者付费模式。*/
    SetBucketRequestPaymentRequest request(BucketName);
    request.setRequestPayer(RequestPayer::Requester);

    auto outcome = client.SetBucketRequestPayment(request);

    if (!outcome.isSuccess()) {
        /*异常处理。*/
        std::cout << "SetBucketRequestPayment fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        return -1;
    }

    /*释放网络等资源。*/
    ShutdownSdk();
    return 0;
}

使用命令行工具ossutil

关于使用ossutil设置请求者付费模式的具体操作, 请参见设置请求者付费模式

使用REST API

如果您的程序自定义要求较高,您可以直接发起REST API请求。直接发起REST API请求需要手动编写代码计算签名。更多信息,请参见PutBucketRequestPayment