To process an HTTP request for multipart/form-data
multi-file upload through Tencent Cloud Serverless, the Base64 encoding capability of API Gateway is needed to encode the multipart
byte stream in the original HTTP request into a string, so that the HTTP event can be serialized and passed to SCF for processing.
After SCF gets and Base64-decodes the body
in the event
passed in by API Gateway, the generated byte stream is the same as that in a regular HTTP request and can be processed normally. In Node.js, it can be processed with libraries such as busboy
.
Node.js
function.After creating the function, you can refer to the following sample code to write the specific logic for processing multipart/form-data
.
// handler.js
"use strict";
const stream = require("stream");
const Busboy = require("busboy");
/** User upload (POST) is processed */
const handlePost = (event) => {
return new Promise((resolve, reject) => {
const busboy = new Busboy({ headers: event.headers });
let html = "";
/** The file is received */
busboy.on("file", (fieldname, file, filename, encoding, mimetype) => {
let buf = Buffer.alloc(0);
console.log({ fieldname });
/** File data blocks are received and spliced into a complete buffer */
file.on("data", function (data) {
buf = Buffer.concat([buf, data]);
});
/** File data block receipt is completed, and the DOM string is generated */
file.on("end", function () {
const imgBase64 = buf.toString("base64");
html += `<img src="data:${mimetype};base64, ${imgBase64}" />`;
});
});
/** multipart/form-data receipt is completed, and the generated HTML is constructed and returned */
busboy.on("finish", function () {
console.log({ msg: "Parse form complete!", html });
resolve({
statusCode: 200,
headers: {
"content-type": "text/html",
},
body: html,
});
});
/**
* busboy needs to process the data in the form of stream pipe.
* After the body is decoded to the buffer,
* it is converted into a stream and finally piped to busboy
*/
const bodyBuf = Buffer.from(event.body, "base64");
var bufferStream = new stream.PassThrough();
bufferStream.end(bodyBuf);
bufferStream.pipe(busboy);
});
};
/** The static file is returned */
const handleGet = (event) => {
const html = `<html><head></head><body>
<form method="POST" enctype="multipart/form-data">
<input type="file" name="image-1" accept="image/*"><br />
<input type="file" name="image-2" accept="image/*"><br />
<input type="submit">
</form>
</body></html>`;
console.log({ msg: "Get form complete!", html });
return {
statusCode: 200,
headers: {
"content-type": "text/html",
},
body: html,
};
};
/** Function entry */
exports.main_handler = async (event, context) => {
const method = event.httpMethod;
/** If the request is a POST request, the user's multipart/form-data is processed and a page displaying the upload result is generated */
if (method === "POST") {
return handlePost(event);
}
/** If the request is a GET request, the page where the file is uploaded is returned */
if (method === "GET") {
return handleGet(event);
}
};
busboy
to decode the multipart/form-data
data.Note:Dependencies must be installed in the
src
folder.
In the trigger management of the function, you need to bind an API Gateway trigger to the function before it can process users' specific HTTP requests. The specific binding method and configuration are as follows:
At this time, if you access the link bound by API Gateway, you will find that although the static page can work, the page does not display the correct result after an image is uploaded. This is because the Base64 encoding feature is disabled in API Gateway by default. As a result, the multipart/form-data
data is incorrectly encoded as a string and passed to the handler function, and busboy cannot decode it.
Therefore, you need to enter API Gateway, find the bound API service, and enable Base64 encoding in the basic configuration.
After the service is opened and published, it can work normally.
You can access the official demo built by Tencent Cloud Serverless to view the effect of file upload.
Was this page helpful?