Using Fetch without abandoning progressive enhancement
The Fetch API offers a cleaner promise-based request interface in current browsers, but support is not universal and a resolved promise does not mean the server returned a successful HTTP status.
Build the server interaction first
Implement the task as a normal link or form submission with redirects, validation and a complete response. JavaScript should intercept only after confirming that the required browser capabilities are present.
Handle the response contract
Check response.ok or the accepted status range before parsing the body, and distinguish network failure from a valid server error. Validate expected content type and display server-provided field errors through the same accessible interface.
Manage duplicate actions
Disable or mark a submitting control, use an idempotency token for operations that cannot be repeated and ignore obsolete responses when the user has moved to a newer state. Fetch has no broadly available cancellation mechanism in early 2016.
Choose polyfills deliberately
If supported older browsers need the enhanced behaviour, load a Promise and Fetch polyfill tested against credentials, headers and error handling. Otherwise allow the native form path rather than serving an incomplete imitation.
Preserve browser behaviour
Update history and focus when an asynchronous action changes the page meaningfully. Confirm back, refresh, bookmarking and opening a link in a new tab still behave as the user expects.
Feature detection decides whether the enhancement runs; server-side form handling remains the compatibility and recovery path.