Cloudflare R2 storage gives free cloud storage for startups and for personal use, but there are monthly usage limits. But it is still worth full.
⭐ Check this image (Reference link)
⚙️Setup:
- Ensure that Node.js is installed on your PC or laptop.
- First, sign up for a Cloudflare account and provide your payment information (this is just to complete your profile; there's no charge as everything is free after account setup).
♨️Steps:
- Create folder 📂 and navigate to that folder.
- Install wrangler (reference link)
npm install wrangler --save-dev
- Login to your wrangler account using this
npx wrangler login
- Now Create a bucket in Cloudflare dashboard.
- Navigate to Cloudflare and select R2 and create bucket.
- Type a name for the bucket and click on "Create Bucket."
- Navigate to bucket you created.
- Now Upload your first Object (any image/video/). Choose either drag and drop or use file upload area.
- Once the upload is complete, you will receive a confirmation message.
- If can't understand (refer to this link)
Bucket Access options (Workers Runtime API)
- Now create new application with C3.
C3 (
create-cloudflare-cli
) is a command-line utility created to assist you in quickly setting up and deploying Workers and Pages applications to Cloudflare.
- To get started open terminal in folder. Run this
npm create cloudflare@latest
- Create your bucket by running this now
npx wrangler r2 bucket create <YOUR_BUCKET_NAME> #enter new bucket name
- To verify if the bucket has been created and to retrieve your list of buckets.
Bind your bucket to a worker (read carefully)
- You need to bind your bucket to a worker, for using with API.
Bindings
A binding refers to the way your Worker connects with external resources like KV Namespaces, Durable Objects, or R2 Buckets. It acts as a runtime variable that the Workers environment supplies to your code.
You can specify a variable name in your wrangler.toml file, which will be linked to these resources during runtime, allowing you to interact with them through this variable. The variable name and its behavior for each binding are defined by you when deploying the Worker. For further details, consult the Environment Variables documentation.
- A binding is specified in the wrangler.toml file located in your Worker project’s directory. Locate the newly created wrangler.toml file in your project directory and update the account_id field with your Cloudflare Account ID.
- To find your Details, navigate
Next, find your Account ID by logging in to the Cloudflare dashboard > Overview > move down to API > and select Click to copy to copy your Account ID. Or run the
wrangler whoami
command [to copy your Account ID]- (reference link)
// wrangler.toml (file)
name = "<YOUR_WORKER_NAME>"
main = "src/index.js"
compatibility_date = "2022-06-30"
account_id = "YOUR_ACCOUNT_ID" # ← Replace with your Account ID.
workers_dev = true
To connect your R2 bucket to your Worker, include the following in your
wrangler.toml
file:
- Update the
binding
property to a valid JavaScript variable identifier.- Set the
bucket_name
to the<YOUR_BUCKET_NAME>
that you used when creating your bucket.
[[r2_buckets]]
binding = 'MY_BUCKET' # <~ valid JavaScript variable name
bucket_name = '<YOUR_BUCKET_NAME>'
Find more detailed information on configuring your Worker in the [Wrangler Configuration documentation]
Access your R2 bucket through your Worker:
- Within your Worker code, your bucket is now accessible via the
MY_BUCKET
variable, allowing you to start interacting with it.
Local Development Mode in Wrangler
- By default,
wrangler dev
operates in local development mode. - In this mode, all actions executed by your local Worker will use local storage on your machine.
- If you want R2 operations performed during development to interact with a real R2 bucket, use
wrangler dev --remote
.
An R2 bucket supports operations to READ, LIST, WRITE, and DELETE objects. Below is an example demonstrating all these operations using the Module Worker syntax. Please add the following snippet to your project's
index.js
file: (If you need clarification on the complete code provided earlier, feel free to ask.)
// src/index.js
var hasValidHeader = (request, env) => {
return request.headers.get("X-Custom-Auth-Key") === env.AUTH_KEY_SECRET;
};
function authorizeRequest(request, env, key) {
switch (request.method) {
case "PUT":
case "DELETE":
return hasValidHeader(request, env);
case "GET":
return true;
default:
return false;
}
}
var src_default = {
async fetch(request, env) {
try {
const url = new URL(request.url);
console.log("Request URL:", url);
const key = url.pathname.slice(1);
if (!authorizeRequest(request, env, key)) {
console.log("Authorization failed");
return new Response("Forbidden", { status: 403 });
}
console.log("Authorization successful");
switch (request.method) {
case "PUT":
console.log("Handling PUT request");
// Parse the request body to extract fields
const formData = await request.formData();
const Filename = formData.get("Filename");
const type = formData.get("type");
const image = formData.get("image");
// Perform image upload and handle additional fields
await env.MY_BUCKET.put(key, image); // Assuming image is the binary image data
console.log(`Uploaded ${Filename} successfully! Type: ${type}`);
return new Response(`Uploaded ${Filename} successfully! Type: ${type}`);
case "GET":
console.log("Handling GET request");
const object = await env.MY_BUCKET.get(key);
if (object === null) {
console.log("Object not found");
return new Response("Object Not Found", { status: 404 });
}
const headers = new Headers();
object.writeHttpMetadata(headers);
headers.set("etag", object.httpEtag);
return new Response(object.body, {
headers
});
case "DELETE":
console.log("Handling DELETE request");
await env.MY_BUCKET.delete(key);
return new Response("Deleted!");
default:
console.log("Invalid request method");
return new Response("Method Not Allowed", {
status: 405,
headers: {
Allow: "PUT, GET, DELETE"
}
});
}
} catch (error) {
console.error("Error:", error);
return new Response("Internal Server Error", { status: 500 });
}
}
};
export {
src_default as default
};
Bucket access and Privacy (reference link)
- Using custom headers we can allow or deny a request based on a known pre-shared key in a header.
- You need to protect bucket operations.
- For PUT and DELETE requests, you'll utilize a new environment variable called
AUTH_KEY_SECRET
, which will be defined later as a Wrangler secret. - For GET requests, you'll restrict access to a specific file. This logic is implemented within an
authorizeRequest
function, while thehasValidHeader
function manages the custom header validation. If all checks are successful, the operation proceeds. - To use this, create a secret key via Wrangler.
- Run this command
npx wrangler secret put AUTH_KEY_SECRET
- This command will ask you to input a secret in your terminal.
npx wrangler secret put AUTH_KEY_SECRET
#Enter the secret text you'd like assigned to the variable
# AUTH_KEY_SECRET on the script named <YOUR_WORKER_NAME>:*********
# 🌀 Creating the secret for script name <YOUR_WORKER_NAME>✨
# Success! Uploaded secret AUTH_KEY_SECRET.
- We use like this in URL (header)
X-Custom-Auth-Key - 123456789 (example code)
This secret is now accessible as
AUTH_KEY_SECRET
in theenv
parameter of your Worker.
Deploy your bucket
- Now that your Worker and Bucket are configured, execute this command in the terminal to deploy to Cloudflare's global network. (reference link)
npx wrangler deploy
- After deploying you get your worker url.
Testing
Now After Deploying, we can use like this:
I am showing in Postman, you can use any other API testing platforms.
- Ensure to include the Header. like this
- Now when press send You get a Successful message, and you can check that file is uploaded to cloud flare R2 account.
- Use different file names; using the same name will overwrite the existing image.
- You can upload various file types, similar to the above.
To view uploaded image:
- Simply append the file name to the end of your Cloudflare Worker URL to view the image. No header is required; just use
URL/your-file-name
.
Note: Ensure that you are using a Cloudflare account within the free limit. Exceeding this limit may result in charges. Stay within the free limit to avoid any worries.
GitHub Complete code (🔗)
Happy Coding 😴 - Be Lazy
Contact DM - Twitter(X)
Contact Mail - sanya.san@myyahoo.com
Top comments (0)