Done with the basics

This commit is contained in:
TomDo1234 2024-04-03 15:42:25 +11:00
parent 5a8d89bfba
commit 6153655888

View File

@ -45,175 +45,75 @@ Workers
:::
### Reading Data
### Overview
In the Lambda handler, the `event.body` attribute is a Base64-encoded string
representing the HTTP request form data. This body must be parsed.
Cloudflare Workers exposes a handler in src/index.(js|ts) when you create a worker project using C3 as per above,
this handler exposes a Request object which can be used to expose the formdata or json of the request to the worker
#### Processing Form Bodies
The `busboy` body parser[^2] is battle-tested in NodeJS deployments.
`busboy` fires a `'file'` event for every file in the form body. The callback
receives a NodeJS stream that should be collected into a Buffer:
```js
/* accumulate the files manually */
var files = {};
bb.on('file', function(fieldname, file, filename) {
/* concatenate the individual data buffers */
var buffers = [];
file.on('data', function(data) { buffers.push(data); });
file.on('end', function() { files[fieldname] = Buffer.concat(buffers); });
});
```
`busboy` fires a `'finish'` event when the body parsing is finished. Callbacks
can assume every file in the form body has been stored in NodeJS Buffer objects.
#### Processing NodeJS Buffers
The SheetJS `read` method[^3] can read the Buffer objects and generate SheetJS
workbook objects[^4] which can be processed with other API functions.
For example, a handler can use `sheet_to_csv`[^5] to generate CSV text:
```js
/* on the finish event, all of the fields and files are ready */
bb.on('finish', function() {
/* grab the first file */
var f = files["upload"];
if(!f) callback(new Error("Must submit a file for processing!"));
/* f[0] is a buffer */
// highlight-next-line
var wb = XLSX.read(f[0]);
/* grab first worksheet and convert to CSV */
var ws = wb.Sheets[wb.SheetNames[0]];
callback(null, { statusCode: 200, body: XLSX.utils.sheet_to_csv(ws) });
});
```
<details><summary><b>Complete Code Sample</b> (click to show)</summary>
This example takes the first uploaded file submitted with the key `upload`,
parses the file and returns the CSV content of the first worksheet.
```js
const XLSX = require('xlsx');
var Busboy = require('busboy');
exports.handler = function(event, context, callback) {
/* set up busboy */
var ctype = event.headers['Content-Type']||event.headers['content-type'];
var bb = Busboy({headers:{'content-type':ctype}});
/* busboy is evented; accumulate the fields and files manually */
var fields = {}, files = {};
bb.on('error', function(err) { callback(null, { body: err.message }); });
bb.on('field', function(fieldname, val) {fields[fieldname] = val });
// highlight-start
bb.on('file', function(fieldname, file, filename) {
/* concatenate the individual data buffers */
var buffers = [];
file.on('data', function(data) { buffers.push(data); });
file.on('end', function() { files[fieldname] = [Buffer.concat(buffers), filename]; });
});
// highlight-end
/* on the finish event, all of the fields and files are ready */
bb.on('finish', function() {
/* grab the first file */
var f = files["upload"];
if(!f) callback(new Error("Must submit a file for processing!"));
/* f[0] is a buffer */
// highlight-next-line
var wb = XLSX.read(f[0]);
/* grab first worksheet and convert to CSV */
var ws = wb.Sheets[wb.SheetNames[0]];
callback(null, { statusCode: 200, body: XLSX.utils.sheet_to_csv(ws) });
});
/* start the processing */
// highlight-next-line
bb.end(Buffer.from(event.body, "base64"));
```ts
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
const data = await request.formData()
// const data = await request.json() if you are receiving a json request
//...
},
};
```
</details>
### Reading Data
The SheetJS `read` method[^4] can read ArrayBuffer objects and generate SheetJS
workbook objects[^5] which can be processed with other API functions.
For example, a handler can use `sheet_to_csv`[^6] to generate CSV text:
```ts
import XLSX from "xlsx";
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
if (request.method === 'POST') {
const data = await request.formData()
// const data = await request.json() if you are doing a json request
const file = data.get('file') as File;
const buffer = await file.arrayBuffer();
const wb = XLSX.read(buffer);
const ws = wb.Sheets[wb.SheetNames[0]];
var b64 = XLSX.write(wb, { type: "base64", bookType: "xlsx" });
return new Response(XLSX.utils.sheet_to_csv(ws))
}
return new Response('Hello World!');
},
};
```
### Writing Data
For safely transmitting binary data, Base64 strings should be used.
The SheetJS `write` method[^6] with the option `type: "base64"` will generate
Base64-encoded strings.
```js
/* sample SheetJS workbook object */
var wb = XLSX.read("S,h,e,e,t,J,S\n5,4,3,3,7,9,5", {type: "binary"});
/* write to XLSX file in Base64 encoding */
var b64 = XLSX.write(wb, { type: "base64", bookType: "xlsx" });
```
The Lambda callback response function accepts options. Setting `isBase64Encoded`
to `true` will ensure the callback handler decodes the data. To ensure browsers
will try to download the response, the `Content-Disposition` header must be set:
```js
callback(null, {
statusCode: 200,
/* Base64-encoded file */
isBase64Encoded: true,
body: b64,
headers: {
/* Browsers will treat the response as the file SheetJSLambda.xlsx */
"Content-Disposition": 'attachment; filename="SheetJSLambda.xlsx"'
}
});
```
<details><summary><b>Complete Code Sample</b> (click to show)</summary>
This example creates a sample workbook object and sends the file in the response:
```js
var XLSX = require('xlsx');
exports.handler = function(event, context, callback) {
/* make workbook */
var wb = XLSX.read("S,h,e,e,t,J,S\n5,4,3,3,7,9,5", {type: "binary"});
/* write to XLSX file in Base64 encoding */
// highlight-next-line
var body = XLSX.write(wb, { type: "base64", bookType: "xlsx" });
/* mark as attached file */
var headers = { "Content-Disposition": 'attachment; filename="SheetJSLambda.xlsx"'};
/* Send back data */
callback(null, {
statusCode: 200,
// highlight-next-line
isBase64Encoded: true,
body: body,
headers: headers
});
```ts
import XLSX from "xlsx";
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
var wb = XLSX.read("S,h,e,e,t,J,S\n5,4,3,3,7,9,5", {type: "binary"});
var data = XLSX.write(wb, { type: "buffer", bookType: "xlsx" });
return new Response(data,{
status: 200,
headers: {
"Content-Disposition": 'attachment; filename="SheetJSCFWorker.xlsx"' //Content disposition will make the browser download the file
}
})
},
};
```
</details>
### Lambda Demo
### Cloudflare Workers Demo
:::note pass
At the time of writing, the Cloudflare Free Tier included an allowance of 1 million
free requests per month and 400 thousand GB-seconds of compute resources.
At the time of writing, the Cloudflare Workers Free Tier included an allowance of 100,000
free requests per day and 10 milliseconds of CPU time per invocation.
:::
0) If you do not have an account, create a new Cloudflare free tier account[^7].
1) If you do not have an account, create a new account[^7].
#### Create Project ZIP
@ -665,10 +565,10 @@ S,h,e,e,t,J,S
[^1]: See ["Node.js compatibility"](https://developers.cloudflare.com/workers/runtime-apis/nodejs/) in the Cloudflare documentation
[^2]: See ["Get started guide"](https://developers.cloudflare.com/workers/get-started/guide/#1-create-a-new-worker-project)
[^3]: [Wrangler documentation](https://developers.cloudflare.com/workers/wrangler/)
[^4]: See ["Workbook Object" in "SheetJS Data Model"](/docs/csf/book) for more details.
[^5]: See [`sheet_to_csv` in "CSV and Text"](/docs/api/utilities/csv#delimiter-separated-output)
[^6]: See [`write` in "Writing Files"](/docs/api/write-options)
[^7]: Registering for a free account [on the Cloudflare Free Tier](https://Cloudflare.amazon.com/free/) requires a valid phone number and a valid credit card.
[^4]: See [`read` in "Reading Files"](/docs/api/parse-options)
[^5]: See ["Workbook Object" in "SheetJS Data Model"](/docs/csf/book) for more details.
[^6]: See [`sheet_to_csv` in "CSV and Text"](/docs/api/utilities/csv#delimiter-separated-output)
[^7]: Registering for a free account [on the Cloudflare Free Tier](https://dash.cloudflare.com/sign-up).
[^8]: The `Cloudflare-sdk` module is distributed [on the public NPM registry](https://npm.im/Cloudflare-sdk)
[^9]: See ["Managing access keys for IAM users"](https://docs.Cloudflare.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html) in the Cloudflare documentation
[^10]: See [`read` in "Reading Files"](/docs/api/parse-options)