Skip to content

Keserasian S3

Gunakan AWS SDK untuk memuat naik, memuat turun dan mengurus fail di IPFS Ninja dengan kod yang sama yang anda gunakan untuk Amazon S3.

Endpoint

https://s3.ipfs.ninja

Kelayakan

S3 API menggunakan kunci API IPFS Ninja anda untuk pengesahan. Kunci API anda berfungsi sebagai kunci akses dan juga kunci rahsia.

Cara mendapatkan kelayakan anda

  1. Pergi ke Dashboard > API Keys
  2. Klik Create API key dan berikan nama (contohnya "S3 access")
  3. Salin kunci penuh dengan segera — ia hanya dipaparkan sekali dan tidak boleh diperoleh semula kemudian

Kunci anda kelihatan seperti ini:

bws_628bba35e9e0079d9ff9c392b1b55a7b
├──────────┘└──────────────────────────┘
 prefix (12 chars)    rest of key

Pemetaan ke kelayakan AWS

AWS ParameterNilaiContoh
accessKeyId12 aksara pertama kunci API andabws_628bba35
secretAccessKeyKunci API penuh (semua 36 aksara)bws_628bba35e9e0079d9ff9c392b1b55a7b
regionSentiasa us-east-1us-east-1

WARNING

Kunci API penuh hanya dipaparkan sekali semasa anda menciptanya. Jika anda kehilangannya, padam kunci tersebut dan cipta yang baru dari halaman API Keys.

Mula Pantas

javascript
import { S3Client, PutObjectCommand, GetObjectCommand } from "@aws-sdk/client-s3";

const s3 = new S3Client({
  endpoint: "https://s3.ipfs.ninja",
  credentials: {
    accessKeyId: "bws_628bba35",
    secretAccessKey: "bws_628bba35e9e0079d9ff9c392b1b55a7b"
  },
  region: "us-east-1",
  forcePathStyle: true
});

// Upload a file
const put = await s3.send(new PutObjectCommand({
  Bucket: "my-project",
  Key: "hello.json",
  Body: JSON.stringify({ hello: "IPFS" }),
  ContentType: "application/json"
}));

console.log("CID:", put.Metadata?.cid);
// CID: bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi

Bucket = Folder

S3 bucket dipetakan ke folder IPFS Ninja anda. Apabila anda memuat naik fail ke bucket, ia disimpan dalam folder yang sepadan. Apabila anda menyenaraikan objek dalam bucket, anda melihat fail dalam folder tersebut.

Operasi S3Setara IPFS Ninja
CreateBucketCipta folder baharu
ListBucketsSenaraikan folder anda
DeleteBucketPadam folder dan semua fail di dalamnya
PutObject ke bucketMuat naik fail ke dalam folder
ListObjectsV2 pada bucketSenaraikan fail dalam folder
javascript
import { ListBucketsCommand, CreateBucketCommand, PutObjectCommand } from "@aws-sdk/client-s3";

// Create a bucket (= create a folder)
await s3.send(new CreateBucketCommand({ Bucket: "nft-metadata" }));

// Upload a file into the folder
await s3.send(new PutObjectCommand({
  Bucket: "nft-metadata",      // ← folder name
  Key: "token-42.json",        // ← filename within the folder
  Body: JSON.stringify({ name: "My NFT #42" })
}));

// List buckets (= list your folders)
const { Buckets } = await s3.send(new ListBucketsCommand({}));
console.log(Buckets);
// [{ Name: "nft-metadata", CreationDate: "2026-04-13T..." }]

TIP

Folder yang dicipta melalui S3 API adalah folder yang sama yang kelihatan di Dashboard anda. Anda boleh menyusun fail dari S3 API, REST API, atau antara muka web — semuanya berkongsi sistem folder yang sama.

INFO

Berbeza dengan Amazon S3, folder IPFS Ninja adalah rata secara lalai. Untuk mencipta struktur bersarang, gunakan endpoint folder REST API dengan parentFolderId. Dari S3 API, gunakan awalan kunci (contohnya images/photo.png) untuk menyusun dalam folder.

Nama bucket adalah unik secara global

Nama bucket berada dalam namespace global merentasi semua pelanggan, sepadan dengan semantik AWS S3. Ini bermakna:

  • Pengguna pertama yang mencipta bucket dengan nama tertentu menuntut nama tersebut secara global.
  • Panggilan CreateBucket berikutnya dengan nama yang sama daripada mana-mana akaun mengembalikan BucketAlreadyExists (409).
  • Jika anda cuba mencipta semula bucket anda sendiri, anda akan mendapat BucketAlreadyOwnedByYou (409).
  • Nama folder anda dalam papan pemuka adalah per-akaun dan masih boleh menjadi apa sahaja — hanya nama bucket yang boleh dilihat melalui S3 yang melalui namespace global.

Jika nama yang anda mahukan telah diambil, pilih nama dengan skop yang berbeza (myapp-photos-2026, acme-nft-metadata) — konvensyen yang sama seperti yang anda gunakan di Amazon S3.

Operasi Yang Disokong

PutObject

Muat naik fail ke IPFS. Fail tersebut akan disemat, diimbas keselamatan, dan CID dikembalikan dalam header ETag dan x-amz-meta-cid.

Untuk mengimport fail CAR dan bukannya fail biasa, tambah header metadata x-amz-meta-import: car. Lihat Import CAR untuk butiran.

javascript
import { PutObjectCommand } from "@aws-sdk/client-s3";
import fs from "fs";

const result = await s3.send(new PutObjectCommand({
  Bucket: "my-project",
  Key: "photo.png",
  Body: fs.readFileSync("photo.png"),
  ContentType: "image/png"
}));

console.log("CID:", result.ETag);
bash
# curl equivalent
curl -X PUT "https://s3.ipfs.ninja/my-project/photo.png" \
  --data-binary @photo.png \
  -H "Content-Type: image/png" \
  --aws-sigv4 "aws:amz:us-east-1:s3" \
  --user "bws_628bba35:bws_628bba35e9e0079d9ff9c392b1b55a7b"

GetObject

Muat turun fail mengikut kunci (nama fail) atau CID.

javascript
import { GetObjectCommand } from "@aws-sdk/client-s3";

const result = await s3.send(new GetObjectCommand({
  Bucket: "my-project",
  Key: "photo.png"
}));

const body = await result.Body.transformToByteArray();
console.log("Size:", body.length);
console.log("CID:", result.Metadata?.cid);

HeadObject

Dapatkan metadata fail tanpa memuat turun kandungan.

javascript
import { HeadObjectCommand } from "@aws-sdk/client-s3";

const head = await s3.send(new HeadObjectCommand({
  Bucket: "my-project",
  Key: "photo.png"
}));

console.log("Size:", head.ContentLength);
console.log("Type:", head.ContentType);
console.log("CID:", head.Metadata?.cid);

DeleteObject

Nyahsemat fail dari IPFS dan padamkannya dari akaun anda.

javascript
import { DeleteObjectCommand } from "@aws-sdk/client-s3";

await s3.send(new DeleteObjectCommand({
  Bucket: "my-project",
  Key: "photo.png"
}));

ListObjectsV2

Senaraikan fail dalam bucket dengan penapisan awalan pilihan dan penomboran halaman.

javascript
import { ListObjectsV2Command } from "@aws-sdk/client-s3";

const list = await s3.send(new ListObjectsV2Command({
  Bucket: "my-project",
  Prefix: "images/",
  MaxKeys: 100
}));

for (const obj of list.Contents ?? []) {
  console.log(obj.Key, obj.Size, obj.ETag); // ETag = CID
}

Muat Naik Berbilang Bahagian

Muat naik fail besar (sehingga 5 GB) menggunakan muat naik berbilang bahagian. AWS SDK mengendalikannya secara automatik:

javascript
import { Upload } from "@aws-sdk/lib-storage";
import fs from "fs";

const upload = new Upload({
  client: s3,
  params: {
    Bucket: "my-project",
    Key: "large-dataset.tar.gz",
    Body: fs.createReadStream("large-dataset.tar.gz"),
    ContentType: "application/gzip"
  },
  partSize: 10 * 1024 * 1024, // 10 MB per part
});

upload.on("httpUploadProgress", (progress) => {
  console.log(`Uploaded ${progress.loaded} of ${progress.total} bytes`);
});

const result = await upload.done();
console.log("CID:", result.ETag);

Atau kawal bahagian secara manual:

javascript
import {
  CreateMultipartUploadCommand,
  UploadPartCommand,
  CompleteMultipartUploadCommand
} from "@aws-sdk/client-s3";

// 1. Start
const { UploadId } = await s3.send(new CreateMultipartUploadCommand({
  Bucket: "my-project",
  Key: "big-file.bin"
}));

// 2. Upload parts
const part1 = await s3.send(new UploadPartCommand({
  Bucket: "my-project",
  Key: "big-file.bin",
  UploadId,
  PartNumber: 1,
  Body: chunk1
}));

// 3. Complete
const result = await s3.send(new CompleteMultipartUploadCommand({
  Bucket: "my-project",
  Key: "big-file.bin",
  UploadId,
  MultipartUpload: {
    Parts: [{ PartNumber: 1, ETag: part1.ETag }]
  }
}));

Contoh Python

python
import boto3

s3 = boto3.client(
    "s3",
    endpoint_url="https://s3.ipfs.ninja",
    aws_access_key_id="bws_628bba35",
    aws_secret_access_key="bws_628bba35e9e0079d9ff9c392b1b55a7b",
    region_name="us-east-1"
)

# Upload
s3.put_object(
    Bucket="my-project",
    Key="data.json",
    Body=b'{"hello": "IPFS"}',
    ContentType="application/json"
)

# List files
response = s3.list_objects_v2(Bucket="my-project")
for obj in response.get("Contents", []):
    print(obj["Key"], obj["Size"])

# Download
result = s3.get_object(Bucket="my-project", Key="data.json")
print(result["Body"].read())

Contoh Go

go
package main

import (
    "context"
    "fmt"
    "strings"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/credentials"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)

func main() {
    client := s3.New(s3.Options{
        BaseEndpoint: aws.String("https://s3.ipfs.ninja"),
        Region:       "us-east-1",
        Credentials:  credentials.NewStaticCredentialsProvider("bws_628bba35", "bws_628bba35e9e0...", ""),
        UsePathStyle: true,
    })

    _, err := client.PutObject(context.TODO(), &s3.PutObjectInput{
        Bucket:      aws.String("my-project"),
        Key:         aws.String("hello.txt"),
        Body:        strings.NewReader("Hello, IPFS!"),
        ContentType: aws.String("text/plain"),
    })
    if err != nil {
        panic(err)
    }
    fmt.Println("Uploaded!")
}

Konfigurasikan CORS (akses SDK pelayar)

Jika anda memanggil S3 API terus dari JavaScript pelayar (SPA, aplikasi wallet, alat papan pemuka), anda perlu konfigurasikan CORS pada bucket terlebih dahulu. Jika tidak, pelayar akan menyekat preflight dan muat naik anda akan gagal dengan No 'Access-Control-Allow-Origin' header is present.

Bentuk yang sama seperti AWS S3 — subresource PutBucketCors / GetBucketCors / DeleteBucketCors:

PutBucketCors

javascript
import { S3Client, PutBucketCorsCommand } from "@aws-sdk/client-s3";

await s3.send(new PutBucketCorsCommand({
  Bucket: "my-bucket",
  CORSConfiguration: {
    CORSRules: [{
      AllowedOrigins: ["http://localhost:3000", "https://myapp.com"],
      AllowedMethods: ["GET", "HEAD", "PUT", "POST", "DELETE"],
      AllowedHeaders: ["*"],
      ExposeHeaders: ["ETag", "x-amz-meta-cid", "x-amz-request-id"],
      MaxAgeSeconds: 3600,
    }],
  },
}));

GetBucketCors

javascript
import { GetBucketCorsCommand } from "@aws-sdk/client-s3";

const { CORSRules } = await s3.send(new GetBucketCorsCommand({ Bucket: "my-bucket" }));
console.log(CORSRules);

DeleteBucketCors

javascript
import { DeleteBucketCorsCommand } from "@aws-sdk/client-s3";

await s3.send(new DeleteBucketCorsCommand({ Bucket: "my-bucket" }));

Had dan lalai

  • Sehingga 5 peraturan setiap bucket (spesifikasi membenarkan 100; kami hadkan kepada 5 untuk mengekalkan respons preflight pelayar tetap ringkas).
  • Jumlah konfigurasi terhad kepada 64 KB apabila diserikan.
  • Jika tiada konfigurasi CORS ditetapkan, preflight pelayar akan ditolak — sepadan dengan sikap lalai AWS S3. Konfigurasikan peraturan eksplisit untuk origin yang benar-benar anda sajikan.

Nota keselamatan dunia sebenar

CORS adalah lapisan kemudahan sisi pelayar, bukan sempadan keselamatan. Setiap panggilan S3 API masih memerlukan tandatangan SigV4 yang sah dikira daripada API key anda — konfigurasi CORS yang longgar tidak membenarkan sesiapa menggunakan bucket anda tanpa kelayakan tersebut. Apa yang CORS cegah: origin yang tidak diingini (contohnya salinan lapuk aplikasi anda pada dev.myapp.com) menghantar permintaan bertandatangan dari konteks pelayar.

Alternatif papan pemuka

Halaman Fail mempunyai entri S3 CORS dalam menu tindakan setiap folder. Storan asas yang sama; jika anda tidak mahu menulis kod PutBucketCors, konfigurasikannya di sana.

Perbezaan Dengan Amazon S3

CiriAmazon S3IPFS Ninja S3
Model storanObjek boleh ubahBeralamat kandungan (CID tidak boleh ubah)
Tingkah laku tulis gantiMenggantikan objek di tempatMencipta CID baharu, CID lama masih boleh diakses
Pengurusan versiDisokongTidak disokong (gunakan CID untuk pengurusan versi)
Penyulitan sisi pelayanDisokongTidak disokong (kandungan berada di IPFS)
Polisi kitaran hayatDisokongTidak disokong
Polisi bucket / ACLDisokongGunakan mod akses gateway
URL pratandatanganDisokongGunakan token muat naik bertandatangan
Saiz objek maksimum5 TB5 GB (berbilang bahagian), 100 MB (PUT tunggal)
KawasanBerbilang kawasanus-east-1 sahaja
Nilai ETagMD5 hashIPFS CID
Header tambahanS3 standardx-amz-meta-cid (IPFS CID)
Format CIDT/BCIDv1 moden (bafy…) untuk muat naik baharu; Qm… lama kekal sah sebagai input
Namespace bucketGlobal (merentasi AWS)Global (merentasi semua akaun IPFS Ninja) — semantik yang sama
CORSPutBucketCors disokongPutBucketCors disokong (had 5 peraturan)

Migrasi Dari Amazon S3

Gantikan konfigurasi klien S3 anda:

diff
 const s3 = new S3Client({
+  endpoint: "https://s3.ipfs.ninja",
   credentials: {
-    accessKeyId: "AKIA...",
-    secretAccessKey: "wJalrX..."
+    accessKeyId: "bws_628bba35",
+    secretAccessKey: "bws_628bba35e9e0..."
   },
   region: "us-east-1",
+  forcePathStyle: true
 });

Panggilan PutObject, GetObject, ListObjectsV2, dan DeleteObject sedia ada anda berfungsi tanpa perubahan.

Migrasi Dari Filebase

Gantikan URL endpoint:

diff
 const s3 = new S3Client({
-  endpoint: "https://s3.filebase.com",
+  endpoint: "https://s3.ipfs.ninja",
   credentials: {
-    accessKeyId: "FILEBASE_KEY",
-    secretAccessKey: "FILEBASE_SECRET"
+    accessKeyId: "bws_628bba35",
+    secretAccessKey: "bws_628bba35e9e0..."
   },
   region: "us-east-1",
   forcePathStyle: true
 });