Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemsSome links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Server-side upload endpoints are not disappearing; the file-byte path is moving. In a modern React application, the browser usually sends file bytes directly to Amazon S3, another S3-compatible object store, or a media platform. Your backend still performs the trusted work: authenticating the user, checking policy, choosing an object key, and issuing a short-lived upload capability such as a presigned URL.
This design reduces application-server bandwidth and can improve progress reporting and scalability, but it does not eliminate authorization, validation, CORS configuration, malware scanning, metadata recording, or cleanup. The sections below show how the flow works, when to use multipart uploads, how to diagnose common failures, and when a managed media service is a better fit.
As an Amazon Associate I earn from qualifying purchases.
What is a direct-to-cloud upload?
A direct-to-cloud upload is a two-plane workflow. The control plane is your application API: it authenticates the user, validates the requested upload, selects a storage key, and returns a narrowly scoped capability. The data plane is the browser’s request to object storage or a media service, carrying the actual bytes without passing through your application server.
A presigned URL is a temporary, permission-limited capability. Amazon S3 documentation says you may use presigned URLs to let someone upload an object without giving that person AWS security credentials or bucket permissions. The URL works only within the permissions granted to the principal that created it, and only until its expiry.
Popular on Amazon
- Read Before You Buy — No Video Output: These adapters support charging and USB 2.0 data transfer, but cannot transmit video signals. Except for standard USB webcams (which use USB data only), they are not compatible with HDMI/DisplayPort cables, video-capable USB-C hubs, or docking stations with video output.
- Convert USB-A Ports to USB-C: Designed to connect USB-C earphones, cables, flash drives, card readers, and other USB-C accessories to standard USB-A ports. Plug-and-play with no drivers or software required.
- Aluminum Alloy Housing: Built with a sturdy aluminum alloy shell that aids in heat dissipation and protects against daily wear and scratches. Designed to maintain a stable and secure connection.
- Compact & Travel-Friendly: The ultra-compact design allows the adapter to stay plugged into your device without blocking adjacent ports or adding bulk, reducing wear and tear on your original USB ports.
- 12-Month Warranty: Backed by a 12-month manufacturer warranty for peace of mind. Designed to meet strict quality control standards for reliable everyday performance.
The request sequence
- Select a file. React receives a
Filefrom an input, drag-and-drop area, or another picker. - Run lightweight browser checks. Check the filename extension, MIME hint, and size to provide immediate feedback. These checks are user experience, not a security boundary.
- Ask your authenticated API for an upload capability. Send metadata such as the intended content type, size, filename, and any business record that will own the file.
- Authorize and presign on the server. The server verifies the user and tenant, applies allowed types and sizes, creates a collision-resistant key, and returns a short-lived PUT URL or POST policy.
- Upload from the browser. Use
fetch,XMLHttpRequest, or an upload library. Send the exact headers and method covered by the signature. - Finalize the record. After a successful response, notify your API or let the server verify the object with a head request. Then trigger scanning, probing, moderation, thumbnailing, or transcoding as needed.
How do I upload files directly to S3 from React?
Use a trusted presigning endpoint followed by a browser PUT. The React component never receives permanent cloud credentials; it receives one capability for one object and one operation.
1. Build the file picker and client checks
function FileUpload() {
const [state, setState] = React.useState({ status: "idle", progress: 0, error: "" });
async function onChange(event) {
const file = event.target.files?.[0];
if (!file) return;
const maxBytes = 25 * 1024 * 1024;
if (file.size > maxBytes) {
setState({ status: "error", progress: 0, error: "File is larger than 25 MB." });
return;
}
setState({ status: "requesting", progress: 0, error: "" });
try {
const capabilityResponse = await fetch("/api/uploads/presign", {
method: "POST",
headers: { "Content-Type": "application/json" },
credentials: "include",
body: JSON.stringify({
filename: file.name,
contentType: file.type || "application/octet-stream",
size: file.size
})
});
if (!capabilityResponse.ok) throw new Error("Could not authorize upload");
const { url, key, contentType } = await capabilityResponse.json();
const uploadResponse = await fetch(url, {
method: "PUT",
headers: { "Content-Type": contentType },
body: file
});
if (!uploadResponse.ok) throw new Error("Object storage rejected the upload");
setState({ status: "complete", progress: 100, error: "" });
// Send key to your API only after this upload succeeds.
await fetch("/api/uploads/complete", {
method: "POST",
headers: { "Content-Type": "application/json" },
credentials: "include",
body: JSON.stringify({ key, size: file.size, contentType })
});
} catch (error) {
setState({ status: "error", progress: 0, error: error.message });
}
}
return <input type="file" onChange={onChange} />;
}
The example deliberately sends the MIME value returned by the presigning service. If the signature includes Content-Type: image/png, the upload request must send exactly that value. Changing it, omitting it, or allowing a library to rewrite it can produce a signature-mismatch response.
2. Presign on the server
Your control-plane endpoint should derive policy from server-side rules rather than trusting a browser-provided filename or type. A typical implementation authenticates the session, checks tenant membership, enforces a maximum size and an allowlist, and generates a key such as tenant-id/user-id/random-id.ext. The random component prevents accidental collisions and makes guessing another user’s object harder.
// Pseudocode: use your cloud SDK's presigner in a real service
POST /api/uploads/presign
requireAuthenticatedUser()
input = parseJson(request)
assert input.size <= policy.maxBytes
assert allowedContentType(input.contentType)
extension = extensionForAllowedType(input.contentType)
key = `${tenantId}/${userId}/${randomId()}${extension}`
url = createShortLivedPutUrl({
bucket: privateBucket,
key,
contentType: input.contentType
})
return { url, key, contentType: input.contentType }
Keep the bucket private. A successful upload does not make an object public. Readers or other services should receive separate, scoped read URLs or access the file through an application authorization layer.
Do I still need a backend for direct uploads?
Yes. You can remove the file transfer from your application server, but you should not remove the trusted control-plane step. The backend remains responsible for authentication, authorization, policy, key generation, and post-upload state.
Responsibilities that belong on the server
- Identify the user and tenant from a session or token rather than from client-supplied identifiers.
- Enforce permitted content types, maximum sizes, quotas, and business relationships.
- Generate non-predictable keys and decide whether overwriting is ever allowed.
- Issue a capability that permits only the intended operation, key, headers, and duration.
- Record an upload as usable only after completion is confirmed and, where appropriate, the object is inspected.
- Queue malware scanning, media probing, moderation, thumbnail generation, or transcoding.
- Clean up abandoned multipart sessions and orphaned objects.
Never put permanent cloud access keys in React code, environment variables exposed to the browser, or downloadable JavaScript bundles. A presigned URL is bearer-like: anyone who obtains it can attempt the permitted operation until it expires.
Why is my S3 upload blocked by CORS?
CORS is the browser permission mechanism that allows a page loaded from one origin to call a different origin. The bucket must allow the exact frontend origin, methods, and request headers used by your upload. CORS does not grant storage authorization; IAM, bucket policy, object ownership, and presigned constraints still decide whether the operation is allowed.
Also popular on Amazon
- 5-in-1 USB-C Hub: Experience comprehensive connectivity featuring a Power Delivery input, two USB-A 2.0 ports, a USB-A 3.0 port, and an HDMI port. (Note: The USB-C power delivery input port is only for connecting an external wall charger to power your laptop and cannot power peripheral devices.)
- 90W Pass-Through Charging: Achieve optimal charging with 90W pass-through power to your laptop, supported by a total input of 100W, with the hub reserving 10W for operational efficiency. (Note: Wall charger not included.)
- Quick Data Transfers: Accelerate your productivity with rapid data transfers using a high-speed 5Gbps USB 3.0 port and two 480Mbps USB 2.0 ports.
- 4K HDMI Display: Enhance your visual experience with a hub capable of delivering 4K resolution at 30Hz in both mirror and extend modes. Please note that this hub is compatible with MacBook (macOS 12 and newer), Windows 10 and 11, ChromeOS, and laptops equipped with DP Alt Mode and Power Delivery. Note: This device is not compatible with Linux.
- What You Get: Anker USB-C Hub (5-in-1, 4K HDMI), welcome guide, 18-month warranty, and our friendly customer service.
CORS configuration checklist
- List each deployed frontend origin explicitly. Avoid a broad wildcard for authenticated or sensitive workflows.
- Allow every method you actually use, commonly
PUTorPOST, plus methods needed by multipart operations. - Allow requested headers such as
Content-Typeand checksum headers. A preflight can fail if the browser asks for a header that the bucket does not allow. - Expose only response headers the browser must read, such as
ETagwhen your service provides it. - Test the production origin, not just
http://localhost. Origins differ by scheme, host, and port.
A CORS error can mask several different problems. Inspect the browser’s preflight request and the storage response, then check whether the URL has expired, the method differs from the signed method, or a signed header is missing. Fixing CORS will not repair an invalid signature or an object-policy denial.
Should I use multipart uploads for large files?
Use multipart transfer when files are large enough that restarting a complete upload is costly or network reliability is a concern. Multipart upload divides an object into parts, uploads parts independently, and completes the object after all parts are accepted. It supports parallelism, retries for individual parts, progress reporting, and resumability, but it adds state and cleanup requirements.
Multipart lifecycle
- Initiate. Your backend starts a multipart upload and receives an upload identifier.
- Presign parts. It creates one presigned URL for each part, or issues them in batches.
- Upload parts. React slices the
File, sends parts in parallel or sequentially, and records each returned part number and entity tag. - Retry selectively. A failed part can be retried without retransmitting successful parts. Limit concurrency to avoid saturating the browser or network.
- Complete. The backend or browser submits the full part list to storage in the required order.
- Abort abandoned sessions. A canceled tab or lost connection can leave uploaded parts consuming storage until you explicitly abort them or a lifecycle rule removes them.
Amplify documents automatic S3 multipart behavior for objects larger than 5 MB. That threshold is an Amplify default, not a universal rule for every product or SDK. Choose a threshold based on your storage service’s limits, network conditions, expected file sizes, and the user experience you want.
Free tools Windows power users keep installed
One-click scans. No signup required.
When a single PUT is still preferable
For small files, one presigned PUT is easier to reason about and has fewer failure states. Multipart is not automatically faster: setup, part coordination, and completion add overhead. Use it when the ability to retry or resume parts outweighs that complexity.
How should I choose object keys and content types?
Treat both values as policy inputs, not cosmetic metadata. S3 replaces an existing object when the same key is uploaded, so a key based only on a user filename can overwrite data. Generate a unique key, namespace it by tenant or user, and make overwrite an explicit, authorized feature.
Do not rely on the filename extension alone. A browser’s MIME hint can be missing or inaccurate. Enforce an allowlist at the presigning endpoint, bind the accepted content type into the signature or POST conditions, and inspect the resulting bytes asynchronously when the product handles untrusted media.
Store the original filename separately for display. Use a normalized extension derived from the accepted type, and escape it when rendering. Keep object keys opaque enough that users cannot infer another tenant’s paths.
Also popular on Amazon
- Sleek 7-in-1 USB-C Hub: Features an HDMI port, two USB-A 3.0 ports, and a USB-C data port, each providing 5Gbps transfer speeds. It also includes a USB-C PD input port for charging up to 100W and dual SD and TF card slots, all in a compact design.
- Flawless 4K@60Hz Video with HDMI: Delivers exceptional clarity and smoothness with its 4K@60Hz HDMI port, making it ideal for high-definition presentations and entertainment. (Note: Only the HDMI port supports video projection; the USB-C port is for data transfer only.)
- Double Up on Efficiency: The two USB-A 3.0 ports and a USB-C port support a fast 5Gbps data rate, significantly boosting your transfer speeds and improving productivity.
- Fast and Reliable 85W Charging: Offers high-capacity, speedy charging for laptops up to 85W, so you spend less time tethered to an outlet and more time being productive.
- What You Get: Anker USB-C Hub (7-in-1), welcome guide, 18-month warranty, and our friendly customer service.
How long should a presigned URL last?
Set expiry long enough for the expected upload, but no longer than necessary. Amplify documents a default of 900 seconds and a session-dependent maximum of one hour for its API. URLs generated through other AWS SDKs can have different limits, so verify the service and SDK you use.
Expiry is not a substitute for authorization. A URL issued to the wrong user remains wrong even if it lasts only a minute. Conversely, an expiry that is too short causes failures on slow connections, clock-skewed devices, or large uploads. If an upload expires, request a fresh capability and restart or resume according to the transfer type.
What are the main direct-upload failure modes?
Signature mismatch
Check the HTTP method, object key, signed headers, content type, checksum, and query string. The value sent by React must match the value used during signing. Also check system clocks when a service reports that a request is not yet valid or has expired.
Expired URL
Ask the control plane for a new URL. For multipart uploads, refresh only the part URLs that expired when your implementation supports it; otherwise restart the affected session according to the storage SDK’s rules.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →CORS preflight failure
Compare the browser’s Origin, Access-Control-Request-Method, and Access-Control-Request-Headers with the bucket rule. Add the deployed origin and exact headers, then retest from the same scheme and hostname users will access.
Upload succeeds but the app shows no file
Do not create the database record before the data-plane request succeeds. After success, send the key to a completion endpoint, and have that endpoint verify existence and expected metadata where practical. Make completion idempotent so a retry cannot create duplicate records.
Duplicate or overwritten objects
Use server-generated random keys and a unique database constraint for the logical upload. If replacement is a feature, require an explicit object identifier and authorization rather than allowing a filename to select the destination.
Also popular on Amazon
- Dual Converters, Infinite Potential:Includes 2× USB C male to USB A female adapters and 2× USB A male to USB C female adapters. Perfect for a wide range of uses—tablets with Bluetooth keyboards, expand USB ports on macbook, and more. Two different converters for all your daily needs
- Next-Level 10Gbps & 3A Charging: No more slow 480Mbps, this usb to usb c adapter has a transfer speed of up to 10Gbps, allowing you to do more transferring in less time. This usb adapter fits both USB A and USB C charger, supporting up to 3A fast charging
- Upgraded Exquisite Craftsmanship: With an aluminum alloy housing and metal connector, the usbc to usb adapter is extremely durable and sturdy. Rigorously tested to withstand more than 10,000 times of plugging and unplugging, ensuring long-lasting performance
- Broad Compatible: The usb c to usb adapter widely supports all USB C/ USB A devices like laptops, tablets, cellphones, car chargers, and phone chargers. Such as compatible with MacBook Pro/Air 2023/2022, Thunderbolt 4/3 Devices,Apple MagSafe Watch 9/8/7/SE/Ultra, iPad Pro 2022/2021, Samsung Galaxy S23/S20/S10, and iPhone 17/16/15 Pro. Plug and play
- Please Note: To reach 10Gbps speed, keep the cable under 3.3 ft. For USB A Male to USB C adapters, try flipping the USB C connector. USB C Male to USB A adapters support bidirectional 10Gbps transfer within 3.3 ft
Orphaned objects and multipart parts
Users can close a tab after an upload but before completion. Track pending uploads, run a periodic reconciliation job, and configure storage lifecycle cleanup for abandoned multipart sessions and objects that never become associated with a valid record.
Recommended Free Tools
Which direct-upload approach fits a React application?
The right choice depends on how much control you need and whether media processing is central to the product.
| Approach | Best fit | Trade-offs |
|---|---|---|
| Hand-built S3 presigned PUT or POST | Teams that need control over keys, policy, IAM, and cost | More backend, CORS, lifecycle, scanning, and UI work |
| AWS Amplify Storage or File Uploader | React teams already using Amplify that want a higher-level component and API | Amplify conventions and AWS coupling; inspect defaults and limits |
| S3 multipart with per-part presigning | Large files, unstable networks, resumability, and detailed progress | More state, completion, retry, and cleanup logic |
| Cloudinary React upload | Image or video products needing widget UX, transformations, and delivery | Vendor-specific upload and media model; verify pricing and program terms |
Use a hand-built flow when policy control matters most
A custom presigning service is appropriate when tenants have different quotas, retention rules, encryption requirements, or key layouts. You own the CORS rules, upload UI, scanning pipeline, and storage lifecycle, so you also own their operational complexity.
Use Amplify when your application already follows its conventions
Amplify can provide higher-level React integration and automatic multipart behavior. Confirm its documented expiry, size threshold, retry behavior, and generated policy before assuming those defaults meet your security or product requirements.
Use a managed media service for transformation-heavy products
A media platform can replace much of the storage plumbing when the requirement includes image and video transformations, delivery, or a ready-made widget. Cloudinary documents a React Upload Widget, unsigned upload presets, and signed uploads whose authentication signature is generated by a backend. Unsigned presets simplify the browser flow but require careful preset restrictions; signed uploads retain server-side authorization.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallHow do I design the post-upload pipeline?
An object existing in storage is not the same as a file being safe or ready for users. Keep the initial completion response small, then process the object asynchronously.
- Mark the upload as pending in your database before issuing the capability, associating it with the authenticated user and intended record.
- After the browser reports success, verify the key and expected metadata. Do not trust a client-supplied size as the only check.
- Queue malware scanning and content inspection for untrusted files.
- For media, probe dimensions, duration, codecs, and actual format before generating thumbnails or enabling playback.
- Change the record to ready only after required checks pass. Keep rejected and quarantined states visible to operators and users.
- Delete or quarantine failed objects according to retention policy.
This separation keeps the upload request fast while preventing partially uploaded or uninspected content from appearing as a finished asset.
Also popular on Amazon
- 5-in-1 Connectivity: Equipped with a 4K HDMI port, a 5 Gbps USB-C data port, two 5 Gbps USB-A ports, and a USB C 100W PD-IN port. Note: The USB C 100W PD-IN port supports only charging and does not support data transfer devices such as headphones or speakers.
- Powerful Pass-Through Charging: Supports up to 85W pass-through charging so you can power up your laptop while you use the hub. Note: Pass-through charging requires a charger (not included). Note: To achieve full power for iPad, we recommend using a 45W wall charger.
- Transfer Files in Seconds: Move files to and from your laptop at speeds of up to 5 Gbps via the USB-C and USB-A data ports. Note: The USB C 5Gbps Data port does not support video output.
- HD Display: Connect to the HDMI port to stream or mirror content to an external monitor in resolutions of up to 4K@30Hz. Note: The USB-C ports do not support video output.
- What You Get: Anker 332 USB-C Hub (5-in-1), welcome guide, our worry-free 18-month warranty, and friendly customer service.
What should I test before shipping?
- Uploads from every production origin and both HTTP methods your design supports.
- Missing, misleading, and disallowed MIME types; files just below and above the size limit.
- Two users attempting to access or complete each other’s keys.
- Expired URLs, device clock skew, slow connections, tab closure, and browser refresh.
- Retries after a 5xx response and duplicate completion requests.
- Multipart interruption, individual-part retry, completion with a missing part, and abort cleanup.
- Private-read behavior: confirm that a storage URL alone does not expose unrelated objects.
- Scanning and media-processing failures, including what the user sees while an asset is pending.
Instrument the control plane separately from the data plane. Log an internal upload identifier, user or tenant, key prefix, requested size and type, presign outcome, completion result, and processing state. Do not log full bearer URLs where they could be reused.
Frequently Asked Questions
Can users upload directly to S3 without seeing AWS credentials?
Yes. A backend can issue a presigned URL or POST policy that grants one temporary operation. The browser uses that capability while permanent credentials remain on the server.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Are presigned URLs safe to put in browser network requests?
They are designed for browser use, but treat them as bearer tokens. Anyone who captures an unexpired URL can attempt its permitted operation, so keep scopes narrow, expiry short, and logs free of reusable URLs.
How can I show upload progress with fetch in React?
The standard fetch upload API does not provide a universally consistent upload-progress event. Use XMLHttpRequest or a browser/library abstraction that exposes upload progress, while keeping the same signed method and headers.
Should uploaded files be public after a successful direct upload?
No. Storage access and upload access are separate decisions. Keep objects private and issue scoped read URLs or serve them through an authorization-aware application endpoint.
What happens if a user closes the tab during a multipart upload?
Some parts may remain stored while the multipart session is incomplete. Record the session identifier, provide an abort path, and use a lifecycle or reconciliation process to remove abandoned sessions.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

