Frontend Single File Upload to Cloud Service Storage
This article explains the common approaches for uploading a single file from a web front‑end to cloud storage, compares backend‑mediated and direct browser uploads, provides SDK and temporary‑URL examples with code, and discusses encryption, request formats, and best‑practice recommendations.
In everyday development, file upload needs such as attachments or avatar images are often handled by sending files to cloud storage and using CDN URLs for fast access.
Common Upload Methods
Backend Upload
The backend provides an upload API; the front‑end sends the file to this endpoint, and the backend forwards it to the cloud storage using a Java SDK. This centralises upload logic but adds server load.
Frontend Upload
Direct browser upload shifts the traffic to the client. Two main patterns are used:
Calling the cloud provider’s JavaScript SDK directly from the front‑end.
Obtaining a temporary signed URL from the backend and uploading the file via a simple HTTP request.
Upload Examples
SDK Upload (Ali‑OSS)
Install the SDK with npm install ali-oss and use the following code to upload exampleobject.txt to examplebucket/exampledir :
const OSS = require('ali-oss');
const client = new OSS({
// initialization parameters
region: 'yourRegion',
accessKeyId: 'yourAccessKeyId',
accessKeySecret: 'yourAccessKeySecret',
stsToken: 'yourSecurityToken',
bucket: 'examplebucket'
});
let data;
const upload = document.getElementById("upload");
const headers = {};
async function putObject(data) {
try {
const result = await client.put("exampledir/exampleobject.txt", data);
console.log(result);
} catch (e) {
console.log(e);
}
}
upload.addEventListener("click", () => {
data = document.getElementById("file").files[0];
putObject(data);
});Temporary URL Upload (STS)
The backend generates a signed policy and returns parameters such as accessid , host , policy , signature , expire , and dir . The front‑end then builds a form‑data request:
const UploadParams = {
"accessid": "LTAI5tBDFVar1hoq****",
"host": "http://post-test.oss-cn-hangzhou.aliyuncs.com",
"policy": "...",
"signature": "VsxOcOudx******z93CLaXPz+4s=",
"expire": 1446727949,
"dir": "user-dirs/"
};
let params = {
'key': key + '${filename}',
'policy': UploadParams.policy,
'OSSAccessKeyId': UploadParams.accessid,
'success_action_status': '200',
'signature': UploadParams.signature,
};
let requestData = new FormData();
Object.keys(params).forEach(k => requestData.append(k, params[k]));
requestData.append('file', fileObj);
axios({ method: 'post', url: UploadParams.host, data: requestData, headers: {} });Encryption and Signature Generation
When a cloud provider requires a signed request, the signature is built in three steps: create a CanonicalRequest, compute a StringToSign, and finally calculate the HMAC‑SHA256 signature using the AccessKey Secret. The following Node.js code demonstrates the process for a generic AWS‑compatible service:
const crypto = require('crypto');
const CryptoJS = require('crypto-js');
function zip() {
const filename = 'uploadTest.png';
const timeStampISO8601Format = '20230101T000000Z';
const dateString = timeStampISO8601Format.substr(0,8);
const uriFileName = uriEscapePath(filename);
const content = 'UNSIGNED-PAYLOAD';
let CanonicalRequest = `PUT\n${uriFileName}\n\ncontent-disposition:attachment;filename=uploadTest.png\ncontent-type:image/png\nhost:oos-cn.ctyunapi.cn\nx-amz-content-sha256:${content}\nx-amz-date:${timeStampISO8601Format}\n\ncontent-disposition;content-type;host;x-amz-content-sha256;x-amz-date\n${content}`;
let hashedCanonicalRequest = crypto.createHash('sha256').update(CanonicalRequest).digest('hex');
const signStr = `AWS4-HMAC-SHA256\n${timeStampISO8601Format}\n${dateString}/cn/s3/aws4_request\n${hashedCanonicalRequest}`;
const AWSAccessKeyId = 'AWSAccessKeyId';
const AWSSecretAccessKey = 'AWSSecretAccessKey';
var DateKey = CryptoJS.HmacSHA256(dateString, `AWS4${AWSSecretAccessKey}`);
var DateRegionKey = CryptoJS.HmacSHA256('cn', DateKey);
var DateRegionServiceKey = CryptoJS.HmacSHA256('s3', DateRegionKey);
var SigningKey = CryptoJS.HmacSHA256('aws4_request', DateRegionServiceKey);
var Signature = CryptoJS.HmacSHA256(signStr, SigningKey);
let Authorization = `AWS4-HMAC-SHA256 Credential=${AWSAccessKeyId}/${dateString}/cn/s3/aws4_request, SignedHeaders=content-disposition;content-type;host;x-amz-content-sha256;x-amz-date, Signature=${Signature}`;
console.log('🚀 ~ Authorization==', Authorization);
}
try { zip(); } catch (error) { console.log('🚀 ~ error', error); }
function uriEscapePath(string) { var parts = []; arrayEach(string.split('/'), part => { parts.push(uriEscape(part)); }); return parts.join('/'); }
function uriEscape(string) { var output = encodeURIComponent(string); output = output.replace(/[^A-Za-z0-9_.~\-%]+/g, escape); output = output.replace(/[*]/g, ch => "%" + ch.charCodeAt(0).toString(16).toUpperCase()); return output; }
function arrayEach(array, iterFunction) { for (var idx in array) { if (Object.prototype.hasOwnProperty.call(array, idx)) { var ret = iterFunction.call(this, array[idx], parseInt(idx,10)); if (ret === {}) break; } } }Common Cloud Service Request Formats
Examples for Alibaba Cloud, Huawei Cloud, and Telecom/Unicloud illustrate the differences between formData and headers based uploads, showing required fields such as OSSAccessKeyId , signature , policy , and the target action URL.
Recommendation
Both SDK and temporary‑URL approaches satisfy front‑end direct uploads; choose SDK for simplicity when security is less critical, and temporary URLs when you need to keep credentials on the backend and maintain a uniform upload flow across providers.
Conclusion
The article covers single‑file upload strategies, code samples, and signature generation, leaving multi‑file and chunked uploads for future discussion.
政采云技术
ZCY Technology Team (Zero), based in Hangzhou, is a growth-oriented team passionate about technology and craftsmanship. With around 500 members, we are building comprehensive engineering, project management, and talent development systems. We are committed to innovation and creating a cloud service ecosystem for government and enterprise procurement. We look forward to your joining us.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.