使用七牛云、阿里云、腾讯云的对象存储上传文件

这篇具有很好参考价值的文章主要介绍了使用七牛云、阿里云、腾讯云的对象存储上传文件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 说明:存在部分步骤省略的情况,请根据具体文档进行操作

 下载相关sdk

composer require qiniu/php-sdk

composer require aliyuncs/oss-sdk-php
composer require alibabacloud/sts-20150401

composer require qcloud/cos-sdk-v5
composer require qcloud_sts/qcloud-sts-sdk

# 如果不需要,请移除,示例:
# composer remove qcloud_sts/qcloud-sts-sdk

use Qiniu\Auth;
use AlibabaCloud\SDK\Sts\V20150401\Sts;
use Darabonba\OpenApi\Models\Config;
use AlibabaCloud\SDK\Sts\V20150401\Models\AssumeRoleRequest;
use AlibabaCloud\Tea\Utils\Utils\RuntimeOptions;

require_once 'vendor/autoload.php'; // 请根据实际情况引入

class oss
{
    public function qiniuPolicy()
    {
        $domain = ''; // 访问oss文件的域名
        $bucket = ''; // 空间名称
        $accessKey = '';
        $secretKey = '';
        $endpoint = ''; // 上传文件的地址,例如:https://up-z2.qiniup.com
        $prefix = ''; // 指定bucket目录前缀
        $dir = $prefix . '/' . date('Ymd') . '/'; // 按日期上传到指定目录

        $expire = time() + 3600;
        $policyArr = [
            'scope' => $bucket,
            'deadline' => $expire,
            'fsizeMin' => 1,
            'fsizeLimit' => 10 * 1024 * 1024,
        ];

        $auth = new Auth($accessKey, $secretKey);
        $token = $auth->uploadToken($bucket, null, 3600, $policyArr);
        if (empty($token)) {
            return [];
        }

        return [
            'endpoint' => $endpoint,
            'host' => $domain,
            'accessId' => '',
            'policy' => '',
            'signature' => '',
            'token' => $token,
            'expire' => $expire,
            'keyTime' => '',
            'algorithm' => '',
            'dir' => $dir,
        ];
    }

    public function aliPolicy()
    {
        // https://help.aliyun.com/zh/oss/use-cases/obtain-signature-information-from-the-server-and-upload-data-to-oss

        $domain = ''; // 访问oss文件的域名
        $bucket = ''; // 空间名称
        $accessKey = '';
        $secretKey = '';
        $endpoint = ''; // 上传文件的地址,例如:https://{bucket名称}.oss-cn-shenzhen.aliyuncs.com
        $prefix = ''; // 指定bucket目录前缀
        $dir = $prefix . '/' . date('Ymd') . '/'; // 按日期上传到指定目录

        // https://help.aliyun.com/zh/oss/developer-reference/postobject#section-d5z-1ww-wdb
        $expire = time() + 3600;
        $policyArr = [
            'expiration' => date('Y-m-d\TH:i:s.000\Z', $expire),
            'conditions' => [
                ['bucket' => $bucket],
                ['content-length-range', 1, 10 * 1024 * 1024],
            ]
        ];
        $policy = base64_encode(json_encode($policyArr));

        // https://help.aliyun.com/zh/oss/developer-reference/postobject#section-wny-mww-wdb
        $signature = base64_encode(hash_hmac('sha1', $policy, $secretKey, true));

        return [
            'endpoint' => $endpoint,
            'host' => $domain,
            'accessId' => $accessKey,
            'policy' => $policy,
            'signature' => $signature,
            'token' => '',
            'expire' => $expire,
            'keyTime' => '',
            'algorithm' => '',
            'dir' => $dir,
        ];
    }

    public function aliSts()
    {
        // https://help.aliyun.com/zh/oss/developer-reference/authorize-access-2

        try {
            // 填写步骤1创建的RAM用户AccessKey。
            $config = new Config([
                "accessKeyId" => "【填写】",
                "accessKeySecret" => "【填写】"
            ]);
            //
            $config->endpoint = "【填写】"; // sts.cn-hangzhou.aliyuncs.com
            $client =  new Sts($config);

            $assumeRoleRequest = new AssumeRoleRequest([
                // roleArn填写步骤2获取的角色ARN,例如acs:ram::175708322470****:role/ramtest。
                "roleArn" => "【填写】",
                // roleSessionName用于自定义角色会话名称,用来区分不同的令牌,例如填写为sessiontest。
                "roleSessionName" => "【填写】",
                // durationSeconds用于设置临时访问凭证有效时间单位为秒,最小值为900,最大值以当前角色设定的最大会话时间为准。本示例指定有效时间为3000秒。
                "durationSeconds" => 3000,
                // policy填写自定义权限策略,用于进一步限制STS临时访问凭证的权限。如果不指定Policy,则返回的STS临时访问凭证默认拥有指定角色的所有权限。
                // 临时访问凭证最后获得的权限是步骤4设置的角色权限和该Policy设置权限的交集。
                // "policy" => ""
            ]);
            $runtime = new RuntimeOptions([]);
            $result = $client->assumeRoleWithOptions($assumeRoleRequest, $runtime);
            //printf("AccessKeyId:" . $result->body->credentials->accessKeyId. PHP_EOL);
            //printf("AccessKeySecret:".$result->body->credentials->accessKeySecret.PHP_EOL);
            //printf("Expiration:".$result->body->credentials->expiration.PHP_EOL);
            //printf("SecurityToken:".$result->body->credentials->securityToken.PHP_EOL);
        }catch (Exception $e){
            // printf($e->getMessage() . PHP_EOL);
            return [];
        }
        
        return $result;
    }

    public function qcloudPolicy()
    {
        // https://cloud.tencent.com/document/product/436/14690

        $domain = ''; // 访问oss文件的域名
        $bucket = ''; // 空间名称
        $accessKey = '';
        $secretKey = '';
        $endpoint = ''; // 上传文件的地址,例如:https://{bucket名称}.cos.ap-guangzhou.myqcloud.com
        $prefix = ''; // 指定bucket目录前缀
        $dir = $prefix . '/' . date('Ymd') . '/'; // 按日期上传到指定目录

        $algorithm = 'sha1';

        $startTime = time();
        $endTime = time() + 3600;
        $expiration = date('Y-m-d\TH:i:s.000\Z', $endTime);
        $keyTime = implode(';', [$startTime, $endTime]);

        $policyArr = [
            'expiration' => $expiration,
            'conditions' => [
                ['acl' => 'default'],
                ['bucket' => $bucket],
                ['q-sign-algorithm' => $algorithm],
                ['q-ak' => $secretId],
                ['q-sign-time' => $keyTime]
            ]
        ];
        $policy = base64_encode(json_encode($policyArr));

        $signKey = hash_hmac($algorithm, $keyTime, $secretKey);
        $stringToSign = sha1(json_encode($policyArr));
        $signature = hash_hmac($algorithm, $stringToSign, $signKey);

        return [
            'endpoint' => $endpoint,
            'host' => $domain,
            'accessId' => $secretId,
            'policy' => $policy,
            'signature' => $signature,
            'token' => '',
            'expire' => $endTime,
            'keyTime' => $keyTime,
            'algorithm' => $algorithm,
            'dir' => $dir,
        ];
    }

    public function qcloudSts()
    {
        // https://cloud.tencent.com/document/product/436/14048
        // https://github.com/tencentyun/qcloud-cos-sts-sdk/blob/master/php/demo/sts_test.php

        $domain = config('oss.qcloud_domain');
        $bucket = config('oss.qcloud_bucket');
        $secretId = config('oss.qcloud_access_key');
        $secretKey = config('oss.qcloud_secret_key');
        $endpoint = config('oss.qcloud_endpoint');
        $prefix = config('oss.qcloud_bucket_key_prefix');
        $dir = $prefix . '/' . date('Ymd') . '/';
        $region = 'ap-guangzhou';

        $sts = new \QCloud\COSSTS\Sts();
        $config = array(
            'url' => 'https://sts.tencentcloudapi.com/', // url和domain保持一致
            'domain' => 'sts.tencentcloudapi.com', // 域名,非必须,默认为 sts.tencentcloudapi.com
            'proxy' => '',
            'secretId' => $secretId, // 固定密钥,若为明文密钥,请直接以'xxx'形式填入,不要填写到getenv()函数中
            'secretKey' => $secretKey, // 固定密钥,若为明文密钥,请直接以'xxx'形式填入,不要填写到getenv()函数中
            'bucket' => $bucket, // 换成你的 bucket
            'region' => $region, // 换成 bucket 所在园区
            'durationSeconds' => 3600, // 密钥有效期
            'allowPrefix' => ['*'], // 这里改成允许的路径前缀,可以根据自己网站的用户登录态判断允许上传的具体路径,例子: a.jpg 或者 a/* 或者 * (使用通配符*存在重大安全风险, 请谨慎评估使用)
            // 密钥的权限列表。简单上传和分片需要以下的权限,其他权限列表请看 https://cloud.tencent.com/document/product/436/31923
            'allowActions' => array(
                // 简单上传
                'name/cos:PutObject',
                'name/cos:PostObject',
                // 分片上传
                'name/cos:InitiateMultipartUpload',
                'name/cos:ListMultipartUploads',
                'name/cos:ListParts',
                'name/cos:UploadPart',
                'name/cos:CompleteMultipartUpload'
            ),
            // 临时密钥生效条件,关于condition的详细设置规则和COS支持的condition类型可以参考 https://cloud.tencent.com/document/product/436/71306
            'condition' => []
        );

        // 获取临时密钥,计算签名
        $tempKeys = $sts->getTempKeys($config);
        return $tempKeys ?: [];

/**
数据如下:
{
  "expiredTime": 1691169303,
  "expiration": "2023-08-04T17:15:03Z",
  "credentials": {
    "sessionToken": "",
    "tmpSecretId": "",
    "tmpSecretKey": ""
  },
  "requestId": "6b274db5-a86b-4e27-a0e9-50f8ae1832f4",
  "startTime": 1691165703
}
*/
    }
}

表单提交到七牛云

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>七牛云oss upload</title>
</head>
<body>
<form method="post" action="{来自于$data里面的endpoint}" enctype="multipart/form-data">
    <input type="hidden" name="key" id="key" value="">
    <input type="hidden" name="token" id="token" value="">
    <input type="hidden" name="crc32" />
    <input type="hidden" name="accept" />
    <input type="file" name="file" id="file" onchange="change(this)" />
    <input type="submit" value="上传文件" id="submit"/>
</form>
<script>
    // 实例化oss类,获取数据
    // $oss = new oss();
    // $data = $oss->qiniuPolicy();

    let eleKey = document.getElementById('key');
    let eleToken = document.getElementById('token');
    eleToken.value = ''; // 来自$data里面的token

    function change(obj) {
        let uploadDir = ''; // 来自$data里面的dir
        let fname = uploadDir + obj.files[0]['name'];
        console.log(fname);
        eleKey.value = fname;
    }
</script>
</body>
</html>

表单提交到阿里云

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>阿里云oss upload</title>
</head>
<body>
<form method="post" action="{来自于$data里面的endpoint}" enctype="multipart/form-data">
    <input type="hidden" name="key" id="key" value="">
    <input type="hidden" name="OSSAccessKeyId" id="accessKey" value="">
    <input type="hidden" name="policy" id="policy" value="">
    <input type="hidden" name="signature" id="signature" value="">
    <input name="file" type="file" id="file" onchange="change(this)" />
    <input type="submit" value="上传文件" id="submit"/>
</form>
<script>
    // 实例化oss类,获取数据
    // $oss = new oss();
    // $data = $oss->aliPolicy();

    let eleKey = document.getElementById('key');
    let eleAccessKey= document.getElementById('accessKey');
    let elePolicy = document.getElementById('policy');
    let eleSignature = document.getElementById('signature');
    eleAccessKey.value = ''; // 来自$data里面的accessId
    elePolicy.value = ''; // 来自$data里面的policy
    eleSignature.value = ''; // 来自$data里面的signature

    function change(obj) {
        let uploadDir = ''; // 来自$data里面的dir
        let fname = uploadDir + obj.files[0]['name'];
        console.log(fname);
        eleKey.value = fname;
    }
</script>
</body>
</html>

 表单提交到阿里云(sts)

说明:需要修改acl权限,不然无法上传文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>阿里云oss upload</title>
</head>
<body>
<input id="file" type="file" />
<button id="upload">上传</button>
<script src="https://gosspublic.alicdn.com/aliyun-oss-sdk-6.16.0.min.js"></script>
<script>
    // yourRegion填写Bucket所在地域。以华东1(杭州)为例,yourRegion填写为oss-cn-hangzhou。
    let region = '';
    
    // 填写Bucket名称。
    let bucket = '';

    // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
    // 从STS服务获取的安全令牌(SecurityToken)。
    let stsData = {
        AccessKeyId:"",
        AccessKeySecret:"",
        Expiration:"",
        SecurityToken:""
    };

    const client = new OSS({
        // yourRegion填写Bucket所在地域。以华东1(杭州)为例,yourRegion填写为oss-cn-hangzhou。
        region: region,
        // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
        accessKeyId: stsData.AccessKeyId,
        accessKeySecret: stsData.AccessKeySecret,
        // 从STS服务获取的安全令牌(SecurityToken)。
        stsToken: stsData.SecurityToken,
        // 填写Bucket名称。
        bucket: bucket
    });

    // 从输入框获取file对象,例如<input type="file" id="file" />。
    let data;
    // 创建并填写Blob数据。
    //const data = new Blob(['Hello OSS']);
    // 创建并填写OSS Buffer内容。
    //const data = new OSS.Buffer(['Hello OSS']);

    const upload = document.getElementById("upload");

    async function putObject (data) {
        try {
            // 填写Object完整路径。Object完整路径中不能包含Bucket名称。
            // 您可以通过自定义文件名(例如exampleobject.txt)或文件完整路径(例如exampledir/exampleobject.txt)的形式实现将数据上传到当前Bucket或Bucket中的指定目录。
            // data对象可以自定义为file对象、Blob数据或者OSS Buffer。
            const result = await client.put(
                "1.png",
                data
            );
            console.log(result);
        } catch (e) {
            console.log(e);
        }
    }

    upload.addEventListener("click", () => {
        const data = file.files[0];
        putObject(data);
    });
</script>
</body>
</html>

表单提交到腾讯云

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>腾讯云oss upload</title>
</head>
<body>
<form method="post" action="{来自于$data里面的endpoint}" enctype="multipart/form-data">
    <input type="hidden" name="key" id="key" value="">
    <input type="hidden" name="acl" id="acl" value="default">
    <input type="hidden" name="policy" id="policy" value="">
    <input type="hidden" name="q-sign-algorithm" id="algorithm" value="">
    <input type="hidden" name="q-ak" id="ak" value="">
    <input type="hidden" name="q-key-time" id="keyTime" value="">
    <input type="hidden" name="q-signature" id="signature" value="">
    <input type="file" name="file" id="file" onchange="change(this)" />
    <input type="submit" value="上传文件" id="submit"/>
</form>
<script>
    // 实例化oss类,获取数据
    // $oss = new oss();
    // $data = $oss->qcloudPolicy();

    let eleKey = document.getElementById('key');
    let elePolicy = document.getElementById('policy');
    let eleAlgorithm = document.getElementById('algorithm');
    let eleAK = document.getElementById('ak');
    let eleKeyTime = document.getElementById('keyTime');
    let eleSignature = document.getElementById('signature');
    elePolicy.value = ''; // 来自$data里面的policy
    eleAlgorithm.value = ''; // 来自$data里面的algorithm
    eleAK.value = ''; // 来自$data里面的accessId
    eleKeyTime.value = ''; // 来自$data里面的keyTime
    eleSignature.value = ''; // 来自$data里面的signature

    function change(obj) {
        let uploadDir = ''; // 来自$data里面的dir
        let fname = uploadDir + obj.files[0]['name'];
        console.log(fname);
        eleKey.value = fname;
    }
</script>
</body>
</html>

表单提交到腾讯云(sts) 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>腾讯云oss upload</title>
</head>
<body>

<input type="file" name="file" id="file"/>
<input type="submit" value="上传文件" id="submit"/>

<!-- 下载https://github.com/tencentyun/cos-js-sdk-v5/blob/master/dist/cos-js-sdk-v5.min.js,并引入cos-js-sdk-v5.min.js -->
<script src="./cos-js-sdk-v5.min.js"></script>

<!-- 详见:https://cloud.tencent.com/document/product/436/11459 -->
<script>
    var cos = new COS({
        // getAuthorization 必选参数
        getAuthorization: function (options, callback) {
            // 异步获取临时密钥
            // 服务端 JS 和 PHP 例子:https://github.com/tencentyun/cos-js-sdk-v5/blob/master/server/
            // 服务端其他语言参考 COS STS SDK :https://github.com/tencentyun/qcloud-cos-sts-sdk
            // STS 详细文档指引看:https://cloud.tencent.com/document/product/436/14048

            // 实例化oss类,获取数据
            // $oss = new oss();
            // $data = $oss->qcloudSts();
            // 服务端响应的数据,示例:
            let data = {
                "expiredTime": 1691382256,
                "expiration": "2023-08-07T04:24:16Z",
                "credentials": {
                    "sessionToken": "",
                    "tmpSecretId": "",
                    "tmpSecretKey": ""
                },
                "requestId": "",
                "startTime": 1691378656
            };

            callback({
                TmpSecretId: data.credentials.tmpSecretId,
                TmpSecretKey: data.credentials.tmpSecretKey,
                SecurityToken: data.credentials.sessionToken,
                // 建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误
                StartTime: data.startTime, // 时间戳,单位秒,如:1580000000
                ExpiredTime: data.expiredTime, // 时间戳,单位秒,如:1580000000
            });

        }
    });

    function handleFileInUploading(file) {
        cos.uploadFile({
            Bucket: '【填写】', /* 填写自己的 bucket,必须字段 */
            Region: '【填写】',     /* 存储桶所在地域,必须字段 */
            Key: file.name,              /* 存储在桶里的对象键(例如:1.jpg,a/b/test.txt,图片.jpg)支持中文,必须字段 */
            Body: file, // 上传文件对象
            SliceSize: 1024 * 1024 * 10,     /* 触发分块上传的阈值,超过5MB使用分块上传,小于5MB使用简单上传。可自行设置,非必须 */
            onProgress: function (progressData) {
                console.log(JSON.stringify(progressData));
            }
        }, function (err, data) {
            if (err) {
                console.log('上传失败', err);
            } else {
                console.log('上传成功');
            }
        });
    }

    /* 选择文件 */
    document.getElementById('submit').onclick = function (e) {
        var file = document.getElementById('file').files[0];
        if (!file) {
            document.getElementById('msg').innerText = '未选择上传文件';
            return;
        }
        handleFileInUploading(file);
    };
</script>
</body>
</html>

参考:

 上传策略_使用指南_对象存储 - 七牛开发者中心

上传凭证_使用指南_对象存储 - 七牛开发者中心

如何进行服务端签名直传_对象存储-阿里云帮助中心

如何使用STS以及签名URL临时授权访问OSS资源(PHP)_对象存储-阿里云帮助中心

对象存储 Web 端直传实践-最佳实践-文档中心-腾讯云

对象存储 POST Object-API 文档-文档中心-腾讯云

对象存储 临时密钥生成及使用指引-最佳实践-文档中心-腾讯云

对象存储 快速入门-SDK 文档-文档中心-腾讯云文章来源地址https://www.toymoban.com/news/detail-628267.html

到了这里,关于使用七牛云、阿里云、腾讯云的对象存储上传文件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【自用笔记】小程序中使用七牛云上传图片

    因为我们之前使用的上传图片在上传比较大的图片时回显耗时很长,所以要求改用七牛云,根据领导给的参考和自己查的资料,做出来一个比较简单的可以满足需求。 首先需要进行准备工作: 内容参考这里(领导给的参考,因为部分准备工作已经做过了,所以我这里就直接

    2024年04月09日
    浏览(29)
  • 使用(七牛云)为例子实现将文件上传到云服务器

    目前,用户的头像、分享生成的长图等文件都是存放在本地的,我们可以将他们存放在云服务器中,此处我们使用七牛云作为例子示范。 创建账户并申请如下的两个bucket,分别是用户头像的存储空间和分享长图的存储空间。 相应的js文件: 文件已经存入七牛云

    2024年02月10日
    浏览(38)
  • flutter开发 - 七牛云上传sdk插件qiniu_flutter_sdk使用

    flutter七牛云上传sdk插件qiniu_flutter_sdk使用 最近在拆分代码,将上传组件设置成插件,下面记录下实现过程。 一、创建flutter_plugin上传插件 这里Android Studio使用创建plugin 填写一下信息 Project name Project location Description Project type Organization Android Language iOS Language Platforms 二、代码实

    2024年02月10日
    浏览(31)
  • 七牛云 图片存储

    在项目中,如用户头像、文章图片等数据往往需要使用单独的文件存储系统来保存 企业中常见的存储方案有两种: a.搭建分布式存储系统, 如FastDFS 数据量非常大, 具备相应的运维管理人员 b.第三方存储 运维成本低, 安全可靠 七牛云作为老牌云存储服务商, 提供了优质的第三方

    2024年02月16日
    浏览(34)
  • uniapp 集成七牛云,上传图片

    4 相册选择照片,或者拍照后,使用上传代码

    2024年02月17日
    浏览(48)
  • 七牛云如何绑定自定义域名-小白操作说明——七牛云对象储存kodo

    七牛云如何绑定自定义域名 **温馨提示:使用加速cdn自定义域名是必须要https的,也就是必须ssl证书,否则类似视频mp4 之类会无法使用。 ​ 编辑切换为居中 添加图片注释,不超过 140 字(可选) 点击首页————对象储存——进入点击空间管理——点击对应空间名称进入

    2024年02月13日
    浏览(27)
  • Element ui Upload 上传图片到七牛云

    action里填写的是七牛云的服务器地址(根据自己申请的区域填,如下图,我这边用的是华北地区) 注意:开发环境可以用http但是上线时需改为https请求,不然请求失败,所以建议都用https 七牛的一张存储区域表 存储区域    区域代码    客户端上传地址    服务端上传地址

    2024年02月14日
    浏览(43)
  • 七牛云如何配置免费 https 阿里云SSL证书

    七牛云注册链接:https://s.qiniu.com/yaQ3am 我之前有个项目是走的 https,这个项目作了一些印刷品,二维码的内容就是 https 的,后来为了适配七牛云的图片服务,就改成了 http。导致再扫二维码的时候都会提示不安全。 以 https 地址进入网站,网站却服务在 http 的时候,证书不匹

    2024年02月07日
    浏览(34)
  • Gin+微服务实现抖音视频上传到七牛云

    如果你对Gin和微服务有一定了解,看本文较容易。 执行命令: Go SDK 的所有的功能,都需要合法的授权。授权凭证的签算需要七牛账号下的一对有效的 Access Key 和 Secret Key ,这对密钥可以通过如下步骤获得: 点击注册🔗开通七牛开发者帐号 如果已有账号,直接登录七牛开发

    2024年02月12日
    浏览(39)
  • 为七牛云分配二级域名作为加速域名(以阿里云为例)

     七牛云官方参考文档可见CNAME配置_使用指南_CDN - 七牛开发者中心 (qiniu.com)  前往七牛云进行添加域名 进入七牛云域名配置中添加我们的二级域名(需要我们有一个已经备案的顶级域名),就在顶级域名之前加一个前缀即可,此处我使用的是qny前缀拼接我的顶级域名,qny.t

    2024年02月03日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包