I am trying to upload an image to Cloudflare from a buffer. I am using the following code:
const cloudflare_url = `https://api.cloudflare.com/client/v4/accounts/${process.env.CLOUDFLARE_ACCNT_ID}/images/v1`;
const roundedCorners = Buffer.from('<svg><rect x="0" y="0" width="200" height="200" rx="50" ry="50"/></svg>');
const form = new FormData();
form.append("file", roundedCorners, "test/corners");
console.log(form.getLengthSync());
const headers = {
Authorization: `Bearer ${process.env.CLOUDFLARE_API_KEY}`,
...form.getHeaders(),
"content-length": form.getLengthSync(),
};
const response = await fetch(cloudflare_url, {
method: "POST",
headers,
body: form,
});
const result = await response.json();
console.log(result);
if (result.success) console.log(`File transferred successfully!`);
else console.log(`Failed to transfer file`);
With the code above, I get the error
Request body length does not match content-length header
If I remove the line "content-length": form.getLengthSync()", I get the error:
'Bad request: incomplete multipart stream'
If I convert the buffer to a Blob before appending it to the form, I get the error:
source.on is not a function
I am at a loss. Do you see anything wrong with the code above or have any alternative solutions?
You can use the npm cloudflare
package instead.
npm install cloudflare
Option 1. Create Client using your API Key & Email Address
import Cloudflare from 'cloudflare';
const client = new Cloudflare({
apiEmail: process.env['CLOUDFLARE_EMAIL'], // This is the default and can be omitted
apiKey: process.env['CLOUDFLARE_API_KEY'], // This is the default and can be omitted
});
Option 2. Create Client using a Token (preferred). Token needs to be generated by navigating to:
Profile
>API Tokens
>Create Token
>Read and write to Cloudflare Stream and Images
>Use Template
>Continue to Summary
>Create Token
import Cloudflare from 'cloudflare';
const client = new Cloudflare({
apiToken: process.env['CLOUDFLARE_TOKEN'], // add token string to process.env
});
Since you are not reading an image from your file system and instead you want to create an svg
from a string you will need jsdom
.
npm install jsdom
Now you can create the svg
within a JSDOM
, extract the svg
, convert to binary and send:
import Cloudflare from 'cloudflare';
import {JSDOM} from 'jsdom';
const client = new Cloudflare({
apiToken: process.env['CLOUDFLARE_TOKEN']
});
const str = '<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg"><rect x="0" y="0" width="200" height="200" rx="50" ry="50" fill="blue"/></svg>';
const dom = new JSDOM(`<!DOCTYPE html><html><body>${str}</body></html>`);
const elem = dom.window.document.querySelector('svg');
const imgBinary = Buffer.from(elem.outerHTML).toString('binary');
const image = await client.images.v1.create({
account_id: yourIdHere,
file: imgBinary
});
console.log(image.id);