Node.js (AWS SDK v3) i HostArena S3: primeri koda
AWS SDK za JavaScript (verzija 3) je zvanična biblioteka za rad sa S3 skladištem iz Node.js aplikacija. Sa HostArena S3 storage je koristite isto kao sa Amazon S3, uz tri razlike u podešavanju: adresa servera, region garage i uključen forcePathStyle.
Šta vam je potrebno
| Podatak | Vrednost | Gde ga nalazite |
|---|---|---|
| Endpoint | https://s3.hostarena.rs | Isti za sve korisnike |
| Region | garage | Obavezno tačno ovako |
| Bucket | vas-bucket | HostArena korisnički panel, kod S3 usluge |
| Access Key | VAS_ACCESS_KEY | HostArena korisnički panel, kod S3 usluge |
| Secret Key | VAS_SECRET_KEY | HostArena korisnički panel, kod S3 usluge |
Potreban vam je Node.js, aktuelna LTS verzija.
Koraci
Napravite projekat i instalirajte S3 modul:
mkdir s3-primer cd s3-primer npm init -y npm install @aws-sdk/client-s3Ključeve ne upisujte direktno u kod. Postavite ih kao promenljive okruženja. Na Linux-u i macOS-u:
export AWS_ACCESS_KEY_ID="VAS_ACCESS_KEY" export AWS_SECRET_ACCESS_KEY="VAS_SECRET_KEY"U Windows PowerShell-u:
$env:AWS_ACCESS_KEY_ID="VAS_ACCESS_KEY" $env:AWS_SECRET_ACCESS_KEY="VAS_SECRET_KEY"Ove komande važe za otvoreni terminal. Na serveru ih obično upisujete u podešavanja servisa, u
.envfajl koji se ne objavljuje ili u alat za tajne podatke.Napravite fajl
primer.js. Sav kod je uasyncfunkcijama, jer SDK radi asinhrono, aawaitvan funkcije ne radi u CommonJS fajlu. Primer otprema fajl, ispisuje spisak i preuzima fajl tako da ga stvarno snimi na disk:const fs = require("node:fs"); const { pipeline } = require("node:stream/promises"); const { S3Client, ListObjectsV2Command, PutObjectCommand, GetObjectCommand, DeleteObjectCommand, } = require("@aws-sdk/client-s3"); // Ključevi se čitaju iz promenljivih okruženja // AWS_ACCESS_KEY_ID i AWS_SECRET_ACCESS_KEY. const s3 = new S3Client({ endpoint: "https://s3.hostarena.rs", region: "garage", forcePathStyle: true, }); const BUCKET = "vas-bucket"; // Otpremanje lokalnog fajla u bucket. async function uploadFile(localPath, key) { await s3.send( new PutObjectCommand({ Bucket: BUCKET, Key: key, Body: fs.createReadStream(localPath), ContentLength: fs.statSync(localPath).size, }) ); console.log("Otpremljeno:", key); } // Spisak fajlova u bucketu (prvih do 1000). async function listFiles() { const result = await s3.send(new ListObjectsV2Command({ Bucket: BUCKET })); for (const obj of result.Contents ?? []) { console.log(obj.Key, obj.Size, "bajtova"); } } // Preuzimanje fajla iz bucketa i snimanje na disk. async function downloadFile(key, localPath) { const result = await s3.send(new GetObjectCommand({ Bucket: BUCKET, Key: key })); await pipeline(result.Body, fs.createWriteStream(localPath)); console.log("Snimljeno:", localPath); } // Brisanje fajla iz bucketa. async function deleteFile(key) { await s3.send(new DeleteObjectCommand({ Bucket: BUCKET, Key: key })); console.log("Obrisano:", key); } async function main() { await uploadFile("bekap.zip", "bekapi/bekap.zip"); await listFiles(); await downloadFile("bekapi/bekap.zip", "vraceno.zip"); } main().catch((err) => { // err.name sadrži S3 kod greške, npr. NoSuchKey ili AccessDenied console.error("Greška:", err.name, "-", err.message); process.exitCode = 1; });Kod preuzimanja,
result.Bodyje tok podataka (stream). Funkcijapipelinega upisuje u fajl i čeka da upis bude završen. Bez toga biste dobili samo odgovor servera, a fajl ne bi bio snimljen.Pokrenite primer (u istom terminalu u kom ste postavili ključeve):
node primer.js
Korisno je znati
ListObjectsV2Commandvraća najviše 1000 fajlova odjednom. Za veće buckete koristitepaginateListObjectsV2iz istog modula.- Za velike fajlove postoji modul
@aws-sdk/lib-storage(klasaUpload), koji fajl deli na delove. - Funkcija
deleteFileje u primeru definisana, ali se ne poziva. Pozovite je samo kada zaista želite da obrišete fajl.
Pažnja: DeleteObjectCommand trajno briše fajl i ne pita za potvrdu. Obrisani fajl se ne može vratiti.
Provera da radi
Stavite mali fajl bekap.zip u folder projekta i pokrenite node primer.js. Ispravan ispis je „Otpremljeno”, spisak fajlova i „Snimljeno: vraceno.zip”, a fajl vraceno.zip se pojavljuje u folderu. Ako vidite „Greška:”, iza nje stoji S3 kod greške.
Najčešći problemi
AuthorizationHeaderMalformed
Region nije dobar. Mora biti tačno garage. Sa us-east-1 ili bilo kojim drugim AWS regionom server odbija zahtev.
InvalidAccessKeyId, AccessDenied ili SignatureDoesNotMatch
Proverite da li su promenljive okruženja postavljene u istom terminalu ili servisu u kom pokrećete program i da ključevi nemaju razmak na početku ili kraju. Ključeve proverite u HostArena korisničkom panelu, kod S3 usluge.
NoSuchBucket
Naziv bucketa nije tačan. Prepišite ga iz HostArena korisničkog panela. Endpoint ostaje https://s3.hostarena.rs, bez naziva bucketa u adresi.
Greška vezana za checksum pri otpremanju
Novije verzije AWS SDK-a same dodaju kontrolni zbir (checksum) svakom otpremanju. Ako dobijete grešku koja pominje checksum, dodajte u podešavanja klijenta sledeće dve opcije:
const s3 = new S3Client({
endpoint: "https://s3.hostarena.rs",
region: "garage",
forcePathStyle: true,
requestChecksumCalculation: "WHEN_REQUIRED",
responseChecksumValidation: "WHEN_REQUIRED",
});Zaključak
Isti princip važi i za druge jezike: PHP, Python (boto3) i Go. Tehnički detalji o adresama i potpisivanju zahteva nalaze se u uputstvu HostArena S3 API: adrese, potpisivanje i kompatibilnost. Nemate S3 uslugu? Pogledajte pakete na stranici HostArena S3 storage. Ako zapne, otvorite tiket u korisničkom panelu.
