Neural Sync Active
Frontend-Backend Integration — AJAX and Fetch API
Registry Synced
Frontend-Backend Integration — AJAX and Fetch API
904 words
5 min read
Reading compass
Now · 🎯 Learning Objectives
Frontend-Backend Integration — AJAX and Fetch API
🎯 Learning Objectives
- Use Fetch API to make HTTP requests from JavaScript
- Send and receive JSON data with the backend
- Handle CORS errors
- Build dynamic UIs that update without page reload
- Handle loading and error states
1. What is AJAX?
AJAX (Asynchronous JavaScript and XML) allows web pages to send/receive data from a server without reloading the page. Despite the "XML" in the name, JSON is now the standard format.
Without AJAX: Submit form → page reloads → wait for full response. With AJAX: Click button → fetch data in background → update only the relevant part of the page.
2. The Fetch API
Modern browsers provide
fetch() for making HTTP requests:javascript// Basic GET request fetch('/api/books') .then(response => response.json()) // Parse JSON .then(data => { console.log(data); // Array of books displayBooks(data); }) .catch(error => { console.error('Error:', error); });
2.1 Async/Await Syntax (Cleaner)
javascriptasync function loadBooks() { try { const response = await fetch('/api/books'); if (!response.ok) { throw new Error(`HTTP ${response.status}`); } const books = await response.json(); displayBooks(books); } catch (error) { showError('Failed to load books'); } }
2.2 POST Request with JSON
javascriptasync function addBook(title, author) { try { const response = await fetch('/api/books', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ title, author }) }); if (!response.ok) { const error = await response.json(); throw new Error(error.error); } const newBook = await response.json(); return newBook; } catch (error) { showError(error.message); } }
3. Complete Example: Book List App
Backend (Flask): Same as the REST API (earlier topic) Frontend (HTML + JS):
html<!-- index.html --> <!DOCTYPE html> <html> <head> <title>Book Manager</title> </head> <body> <h1>Books</h1> <form id="addBookForm"> <input type="text" id="title" placeholder="Title" required> <input type="text" id="author" placeholder="Author" required> <button type="submit">Add Book</button> </form> <ul id="bookList"></ul> <script> const API = '/api/books'; // Load books on page load async function loadBooks() { const response = await fetch(API); const books = await response.json(); const list = document.getElementById('bookList'); list.innerHTML = books.map(book => ` <li> <strong>${book.title}</strong> by ${book.author} <button onclick="deleteBook(${book.id})">Delete</button> </li> `).join(''); } // Add book document.getElementById('addBookForm').addEventListener('submit', async (e) => { e.preventDefault(); const title = document.getElementById('title').value; const author = document.getElementById('author').value; await fetch(API, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ title, author }) }); document.getElementById('title').value = ''; document.getElementById('author').value = ''; loadBooks(); // Refresh the list }); // Delete book async function deleteBook(id) { await fetch(`${API}/${id}`, { method: 'DELETE' }); loadBooks(); // Refresh the list } // Initial load loadBooks(); </script> </body> </html>
4. CORS (Cross-Origin Resource Sharing)
When frontend and backend are on different origins (domain, port, or protocol), the browser blocks requests:
pseudoOrigin: http://localhost:3000 (React dev server) Request to: http://localhost:5000 (Flask API) → CORS error!
Flask-CORS fix:
python# pip install flask-cors from flask_cors import CORS app = Flask(__name__) CORS(app) # Allow all origins (development only) # For production, restrict origins: CORS(app, origins=['https://myapp.com'])
5. Practice Questions
Q1: What is AJAX and why is it used?Answer: AJAX allows web pages to send/receive data from a server without reloading the entire page. This creates smoother user experiences (dynamic updates, partial page refreshes, real-time validation). Q2: How does the fetch() API work?Answer:fetch(url, options)returns a Promise that resolves to a Response object. You callresponse.json()(or.text(),.blob()) to extract the body. Useasync/awaitor.then()chains. Q3: What is CORS and when does it matter?Answer: CORS (Cross-Origin Resource Sharing) is a browser security mechanism that blocks requests from a different origin (domain, port, protocol). It matters when your frontend (e.g., on port 3000) talks to a backend on a different port (e.g., 5000). The server must include CORS headers to allow this. Q4: How do you handle errors with fetch?Answer: Checkresponse.ok(true for 200-299 status codes). If false, read the error response withresponse.json()orresponse.text(). Use try/catch for network errors. Q5: What is the purpose ofe.preventDefault()in form handlers?Answer: Prevents the browser's default form submission behavior (which would reload the page). When using AJAX, we want to handle submission via JavaScript instead. Q6: How do you send JSON data with fetch?Answer: Set the method to POST/PUT, setContent-Type: application/jsonheader, and pass the data asJSON.stringify(obj)in the body:javascriptfetch('/api/data', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ key: 'value' }) });Q7: Why do we need theasynckeyword before functions usingawait?Answer:awaitcan only be used inside functions declared withasync. Anasyncfunction automatically returns a Promise (wrapping the return value). This is how JavaScript implements asynchronous operations. Q8: How would you show a loading spinner during an AJAX request?javascriptasync function loadData() { showSpinner(); // Show loading indicator try { const data = await fetch('/api/data').then(r => r.json()); displayData(data); } catch (error) { showError(error); } finally { hideSpinner(); // Always hide when done } }
📐 Key Concepts
| Concept | Frontend | Backend |
|---|---|---|
| GET data | fetch('/api/items') | return jsonify(items) |
| POST data | fetch(url, {method:'POST', body: JSON.stringify(data)}) | request.get_json() |
| JSON format | response.json() | jsonify() |
| Error handling | if (!response.ok) | return jsonify(error), 400 |
| CORS | Browser blocks cross-origin | CORS(app) to allow |