---
title: 'Получить ссылку на объект'
sidebar_label: 'Получить ссылку на объект'
description: 'Как получить ссылку на объект в публичном бакете или создать ссылку на объект в приватном бакете'
sidebar_position: 2
---

import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
import {TabItemLabel} from 'docs-kit/components'
import Formbricks from '@theme/MDXComponents/Formbricks'
import LinkIcon from 'docs-kit/icons/link'
import MoreVerticalIcon from 'docs-kit/icons/more-vertical'
import CopyIcon from 'docs-kit/icons/copy'

# Получить ссылку на объект

Вы можете:

* [получить ссылку на объект в публичном бакете](#obtain-link-to-object-in-public-bucket) — все объекты доступны через [публичные домены](/s3/manage/domains.mdx) хранилища;
* [получить ссылку на объект в приватном бакете](#obtain-link-to-object-in-private-bucket) — ссылку можно сделать постоянной или временной.

Мы не рекомендуем использовать кириллицу в именах объектов.
Если вы используете кириллицу, для работы с ссылками на такие объекты кодируйте часть ссылки с кириллицей.

## Получить ссылку на объект в публичном бакете \{#obtain-link-to-object-in-public-bucket}

1. В [панели управления](https://my.selectel.ru/storage/) в верхнем меню нажмите **Продукты** и выберите **S3**.
2. Перейдите в раздел **Бакеты**.
3. Откройте страницу бакета → вкладка **Объекты**.
4. В строке объекта нажмите <LinkIcon />.
5. В строке ссылки нажмите <CopyIcon />.

## Получить ссылку на объект в приватном бакете \{#obtain-link-to-object-in-private-bucket}

Вы можете:

* [создать постоянную или временную ссылку в панели управления](#create-link-in-control-panel). Ссылка будет сохранена в специальном бакете `links` в виде объекта с таким же именем, как у объекта, на который указывает ссылка. Доступ к объекту будет через [публичный домен бакета](/s3/manage/domains.mdx#bucket-public-domain) `links`;
* [получить временную ссылку через подписанный URL](#obtain-temporary-link-via-presigned-url);
* [получить постоянную ссылку через скрипт](#obtain-permanent-link-via-script);
* получить постоянную или временную ссылку через инструменты, например [Rclone](/s3/tools/rclone.mdx#obtain-link-to-object), [AWS CLI](/s3/tools/aws-cli.mdx#obtain-link-to-object), [Cyberduck](/s3/tools/cyberduck.mdx#obtain-link-to-object) и [S3 Browser](/s3/tools/s3-browser.mdx#obtain-link-to-object).

### Создать ссылку в панели управления \{#create-link-in-control-panel}

Вы можете получить временную или постоянную ссылку на объект в приватном бакете.

Объект в приватном бакете будет доступен по ссылке вида `https://<bucket_public_domain>/<object_name>`, где:

* `<bucket_public_domain>` — [публичный домен бакета](/s3/manage/domains.mdx#bucket-public-domain);
* `<object_name>` — имя объекта.

Когда вы впервые создаете ссылку на объект в приватном бакете, в проекте автоматически создается публичный бакет `links`.
Созданная ссылка добавляется в него в виде объекта с таким же именем, как у основного объекта.
Объекты в бакете `links` имеют нулевой размер и не потребляют [объем хранения](/s3/about/payment.mdx#storage-volume).
Если вы настроите ссылку как временную, объект со ссылкой автоматически удалится из бакета `links`, когда ссылка перестанет работать.

Чтобы создать ссылку:

1. В [панели управления](https://my.selectel.ru/storage/) в верхнем меню нажмите **Продукты** и выберите **S3**.
2. Перейдите в раздел **Бакеты**.
3. Откройте страницу бакета → вкладка **Объекты**.
4. В меню <MoreVerticalIcon /> объекта выберите **Открыть доступ**.
5. Опционально: в поле **Адрес ссылки** измените имя объекта, которое будет отображаться в ссылке, или оставьте текущее.
6. Опционально: чтобы по ссылке можно было перейти только один раз, отметьте чекбокс **Одноразовая ссылка**.
7. Опционально: чтобы ограничить время действия ссылки, отметьте чекбокс **Временные ограничения** и выберите один из вариантов:

   * **Удалить через** — ссылка перестанет работать через выбранный промежуток времени после создания;
   * **Удалить в указанное время** — ссылка перестанет работать в выбранную дату и время.
8. Нажмите **Создать ссылку**.
9. Чтобы скопировать ссылку, нажмите <CopyIcon />. Вы сможете [скопировать ее](#obtain-link-to-object-in-public-bucket) позднее в бакете `links`.

### Получить временную ссылку через подписанный URL \{#obtain-temporary-link-via-presigned-url}

С помощью подписанных URL (Presigned URLs) AWS SDK можно получить временную ссылку на объект.
Подробнее в инструкции [Sharing objects with presigned URLs](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ShareObjectPreSignedURL.html) документации AWS.

<Tabs queryString="presigned-url">
  <TabItem value="python">
    <TabItemLabel>
      Python
    </TabItemLabel>

    Пример скрипта:

    ```python
    import boto3

    ACCESS_KEY = "<access_key>"      
    SECRET_KEY = "<secret_key>"      
    ENDPOINT_URL = "<s3_domain>" 
    BUCKET_NAME = "<bucket_name>"       
    OBJECT_KEY = "<path_to_object>"      
    EXPIRES_IN = "<time>"

    s3 = boto3.client(
        "s3",
        aws_access_key_id=ACCESS_KEY,
        aws_secret_access_key=SECRET_KEY,
        endpoint_url=ENDPOINT_URL,
    )

    url = s3.generate_presigned_url(
        ClientMethod="get_object",
        Params={"Bucket": BUCKET_NAME, "Key": OBJECT_KEY},
        ExpiresIn=EXPIRES_IN
    )

    print("\PresignedUrl
    :")
    print(url)
    ```

    Укажите:

    * `<access_key>` — значение поля **Access key** из [S3-ключа](/s3/manage/manage-access.mdx#issue-s3-key);
    * `<secret_key>` — значение поля **Secret key** из [S3-ключа](/s3/manage/manage-access.mdx#issue-s3-key);
    * `<s3_domain>` — [домен S3 API](/s3/manage/domains.mdx#s3-api-domains) в зависимости от пула, в котором находится бакет;
    * `<bucket_name>` — имя бакета;
    * `<path_to_object>` — путь к объекту в бакете;
    * `<time>` — время действия ссылки в секундах.
  </TabItem>

  <TabItem value="php">
    <TabItemLabel>
      PHP
    </TabItemLabel>

    Пример скрипта:

    ```php
    <?php
    require 'vendor/autoload.php';

    use Aws\S3\S3Client;
    use Aws\Exception\AwsException;

    $selectelS3 = new S3Client([
        'version' => 'latest',
        'region'  => '<pool>',
        'endpoint' => '<s3_domain>':,
        'use_path_style_endpoint' => true,
        'credentials' => [
            'key'    => '<access_key>',
            'secret' => '<secret_key>',
        ],
    ]);

    $bucket = '<bucket_name>';
    $key = '<path_to_object>';

    try {
        $cmd = $selectelS3->getCommand('GetObject', [
            'Bucket' => $bucket,
            'Key'    => $key
        ]);

        $request = $selectelS3->createPresignedRequest($cmd, '<time>');
        $presignedUrl = (string)$request->getUri();

        echo "Публичная ссылка: $presignedUrl\n";
    } catch (AwsException $e) {
        echo "Ошибка генерации ссылки: " . $e->getMessage() . "\n";
    }
    ```

    Укажите:

    * `<pool>` — [пул](/infrastructure/locations.mdx#pool), в котором находится бакет;
    * `<s3_domain>` — [домен S3 API](/s3/manage/domains.mdx#s3-api-domains) в зависимости от пула, в котором находится бакет;
    * `<access_key>` — значение поля **Access key** из [S3-ключа](/s3/manage/manage-access.mdx#issue-s3-key);
    * `<secret_key>` — значение поля **Secret key** из [S3-ключа](/s3/manage/manage-access.mdx#issue-s3-key);
    * `<bucket_name>` — имя бакета;
    * `<path_to_object>` — путь к объекту в бакете;
    * `<time>` — время действия ссылки, например `+1 hour`.
  </TabItem>

  <TabItem value="javascript">
    <TabItemLabel>
      JavaScript
    </TabItemLabel>

    Пример скрипта:

    ```js
    import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";
    import { getSignedUrl } from "@aws-sdk/s3-request-presigner";

    const client = new S3Client({
    region: "<pool>",
    endpoint: "<s3_domain>",
    forcePathStyle: true,
    credentials: {
        accessKeyId: "<access_key>",
        secretAccessKey: "<secret_key>",
    },
    });

    async function generatePresignedUrl() {
    const bucket = "<bucket_name>";   
    const key = "<path_to_object>";          

    const command = new GetObjectCommand({ Bucket: bucket, Key: key });

    const url = await getSignedUrl(client, command, { expiresIn: <time> });
    console.log("Presigned URL:", url);
    }

    generatePresignedUrl().catch(console.error);
    ```

    Укажите:

    * `<pool>` — [пул](/infrastructure/locations.mdx#pool), в котором находится бакет;
    * `<s3_domain>` — [домен S3 API](/s3/manage/domains.mdx#s3-api-domains) в зависимости от пула, в котором находится бакет;
    * `<access_key>` — значение поля **Access key** из [S3-ключа](/s3/manage/manage-access.mdx#issue-s3-key);
    * `<secret_key>` — значение поля **Secret key** из [S3-ключа](/s3/manage/manage-access.mdx#issue-s3-key);
    * `<bucket_name>` — имя бакета;
    * `<path_to_object>` — путь к объекту в бакете;
    * `<time>` — время действия ссылки в секундах.
  </TabItem>

  <TabItem value="java">
    <TabItemLabel>
      Java
    </TabItemLabel>

    Пример скрипта:

    ```js
    package com.example;

    import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
    import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
    import software.amazon.awssdk.regions.Region;
    import software.amazon.awssdk.services.s3.S3Client;
    import software.amazon.awssdk.services.s3.model.GetObjectRequest;
    import software.amazon.awssdk.services.s3.model.S3Exception;
    import software.amazon.awssdk.services.s3.presigner.S3Presigner;
    import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest;
    import software.amazon.awssdk.services.s3.presigner.model.PresignedGetObjectRequest;

    import java.net.URI;
    import java.time.Duration;

    public class SelectelS3PresignedUrlGenerator {
        public static void main(String[] args) {

            String endpoint = "<s3_domain>"; 
            String region = "<pool>";
            String accessKey = "<access_key>";
            String secretKey = "<secret_key>";
            String bucketName = "<bucket_name>";
            String objectKey = "<path_to_object>";

            StaticCredentialsProvider credentials = StaticCredentialsProvider.create(
                    AwsBasicCredentials.create(accessKey, secretKey)
            );

            S3Client s3Client = S3Client.builder()
                    .endpointOverride(URI.create(endpoint))
                    .region(Region.of(region))
                    .credentialsProvider(credentials)
                    .build();

            S3Presigner presigner = S3Presigner.builder()
                    .endpointOverride(URI.create(endpoint))
                    .region(Region.of(region))
                    .credentialsProvider(credentials)
                    .build();

            try {
                GetObjectRequest getObjectRequest = GetObjectRequest.builder()
                        .bucket(bucketName)
                        .key(objectKey)
                        .build();

                GetObjectPresignRequest presignRequest = GetObjectPresignRequest.builder()
                        .signatureDuration(Duration.ofMinutes(<time>))
                        .getObjectRequest(getObjectRequest)
                        .build();

                PresignedGetObjectRequest presignedRequest = presigner.presignGetObject(presignRequest);

                System.out.println("Presigned URL: " + presignedRequest.url());
                System.out.println("Expires at: " + presignedRequest.expiration());

            } catch (S3Exception e) {
                System.err.println("Ошибка при генерации presigned URL: " + e.awsErrorDetails().errorMessage());
            } finally {
                s3Client.close();
                presigner.close();
            }
        }
    }
    ```

    Укажите:

    * `<s3_domain>` — [домен S3 API](/s3/manage/domains.mdx#s3-api-domains) в зависимости от пула, в котором находится бакет;
    * `<pool>` — [пул](/infrastructure/locations.mdx#pool), в котором находится бакет;
    * `<access_key>` — значение поля **Access key** из [S3-ключа](/s3/manage/manage-access.mdx#issue-s3-key);
    * `<secret_key>` — значение поля **Secret key** из [S3-ключа](/s3/manage/manage-access.mdx#issue-s3-key);
    * `<bucket_name>` — имя бакета;
    * `<path_to_object>` — путь к объекту в бакете;
    * `<time>` — время действия ссылки в минутах.
  </TabItem>

  <TabItem value="go">
    <TabItemLabel>
      Go
    </TabItemLabel>

    Пример скрипта:

    ```go
    package main 
    import (
        "context"
        "fmt"
        "log"
        "time"
        "github.com/aws/aws-sdk-go-v2/aws"
        "github.com/aws/aws-sdk-go-v2/config"
        "github.com/aws/aws-sdk-go-v2/credentials"
        "github.com/aws/aws-sdk-go-v2/service/s3"
    )
    func main() {
        cfg, err := config.LoadDefaultConfig(context.TODO(),
            config.WithCredentialsProvider(
                credentials.NewStaticCredentialsProvider("<access_key>", "<secret_key>", ""),
            ),
        )
        if err != nil {
            log.Fatal(err.Error())
        }
        client := s3.NewFromConfig(cfg, func(o *s3.Options) {
            o.BaseEndpoint = aws.String("<s3_domain>")
            o.Region = "<pool>"
        })
        presignClient := s3.NewPresignClient(client)
        req, err := presignClient.PresignGetObject(context.TODO(), &s3.GetObjectInput{
            Bucket: aws.String("<bucket_name>"),
            Key:    aws.String("<path_to_object>"),
        }, s3.WithPresignExpires(<time>))
        if err != nil {
            log.Fatal(err.Error())
        }
        fmt.Println("Публичная ссылка:", req.URL)
    }
    ```

    Укажите:

    * `<access_key>` — значение поля **Access key** из [S3-ключа](/s3/manage/manage-access.mdx#issue-s3-key);
    * `<secret_key>` — значение поля **Secret key** из [S3-ключа](/s3/manage/manage-access.mdx#issue-s3-key);
    * `<s3_domain>` — [домен S3 API](/s3/manage/domains.mdx#s3-api-domains) в зависимости от пула, в котором находится бакет;
    * `<pool>` — [пул](/infrastructure/locations.mdx#pool), в котором находится бакет;
    * `<bucket_name>` — имя бакета;
    * `<path_to_object>` — путь к объекту в бакете;
    * `<time>` — время действия ссылки, например `24*time.Hour`.
  </TabItem>
</Tabs>

### Получить постоянную ссылку через скрипт \{#obtain-permanent-link-via-script}

<Tabs queryString="scripts">
  <TabItem value="python">
    <TabItemLabel>
      Python
    </TabItemLabel>

    Пример скрипта:

    ```python
    import boto3

    def get_public_url(bucket_uuid: str, object_key: str) -> str:
        
        return f"https://{bucket_uuid}.selstorage.ru/{object_key}"

    if __name__ == "<file_name>":
        bucket_uuid = "<uuid>"
        object_key = "<path_to_object>"
        url = get_public_url(bucket_uuid, object_key)
        print("Public URL:", url)
    ```

    Укажите:

    * `<file_name>` — имя Python-файла;
    * `<uuid>` — уникальный идентификатор бакета, можно посмотреть в [публичном домене бакета](/s3/manage/domains.mdx#bucket-public-domain);
    * `<path_to_object>` — путь к объекту в бакете.
  </TabItem>

  <TabItem value="php">
    <TabItemLabel>
      PHP
    </TabItemLabel>

    Пример скрипта:

    ```php
    <?php
    function get_public_url(string $bucket_uuid, string $object_key): string {
        return "https://{$bucket_uuid}.selstorage.ru/{$object_key}";
    }

    $bucket_uuid = "<uuid>";
    $object_key = "<path_to_object>";

    $public_url = get_public_url($bucket_uuid, $object_key);
    echo "Public URL: " . $public_url . PHP_EOL;
    ```

    Укажите:

    * `<uuid>` — уникальный идентификатор бакета, можно посмотреть в [публичном домене бакета](/s3/manage/domains.mdx#bucket-public-domain);
    * `<path_to_object>` — путь к объекту в бакете.
  </TabItem>

  <TabItem value="javascript">
    <TabItemLabel>
      JavaScript
    </TabItemLabel>

    Пример скрипта:

    ```js
    function getPublicUrl(bucketUuid, objectKey) {
        return `https://${bucketUuid}.selstorage.ru/${objectKey}`;
    }

    const bucketUuid = "<uuid>";
    const objectKey = "<path_to_object>";

    const publicUrl = getPublicUrl(bucketUuid, objectKey);
    console.log("Public URL:", publicUrl);
    ```

    Укажите:

    * `<uuid>` — уникальный идентификатор бакета, можно посмотреть в [публичном домене бакета](/s3/manage/domains.mdx#bucket-public-domain);
    * `<path_to_object>` — путь к объекту в бакете.
  </TabItem>

  <TabItem value="java">
    <TabItemLabel>
      Java
    </TabItemLabel>

    Пример скрипта:

    ```js
    public class SelectelPublicLink {

        public static String getPublicUrl(String bucketUuid, String objectKey) {
            return "https://" + bucketUuid + ".selstorage.ru/" + objectKey;
        }

        public static void main(String[] args) {

            String bucketUuid = "<uuid>";
            String objectKey = "<path_to_object>";

            String publicUrl = getPublicUrl(bucketUuid, objectKey);
            System.out.println("Public URL: " + publicUrl);
        }
    }
    ```

    Укажите:

    * `<uuid>` — уникальный идентификатор бакета, можно посмотреть в [публичном домене бакета](/s3/manage/domains.mdx#bucket-public-domain);
    * `<path_to_object>` — путь к объекту в бакете.
  </TabItem>

  <TabItem value="go">
    <TabItemLabel>
      Go
    </TabItemLabel>

    Пример скрипта:

    ```go
    package main

    import (
        "fmt"
    )

    func getPublicURL(bucketUUID, objectKey string) string {
        return fmt.Sprintf("https://%s.selstorage.ru/%s", bucketUUID, objectKey)
    }

    func main() {

        bucketUUID := "<uuid>"
        objectKey := "<path_to_object>"

        publicURL := getPublicURL(bucketUUID, objectKey)
        fmt.Println("Public URL:", publicURL)
    }
    ```

    Укажите:

    * `<uuid>` — уникальный идентификатор бакета, можно посмотреть в [публичном домене бакета](/s3/manage/domains.mdx#bucket-public-domain);
    * `<path_to_object>` — путь к объекту в бакете.
  </TabItem>
</Tabs>

<Formbricks />
