# How to Use jQuery AJAX to Submit a Form Without a Page Reload: Integrating with Python Requests

> Submit forms with jQuery AJAX and prevent page reloads. Learn how to integrate client-side submissions with Python Requests for seamless data handling. Enhance your web applications today.

- Repository: [Python Software Foundation/requests](https://github.com/psf/requests)
- Tags: tutorial
- Published: 2026-02-18

---

**Use jQuery's `$.ajax()` method with `event.preventDefault()` to stop page reloads on the client side, while the Python Requests library handles the incoming data on the server side or forwards it to external APIs.**

The Python Requests library (`psf/requests`) is a server-side HTTP client that complements front-end jQuery AJAX calls. While Requests does not execute browser-based JavaScript, it provides the backend infrastructure to receive, process, and forward form data submitted without page reloads using jQuery AJAX.

## Client-Side Implementation with jQuery AJAX

To submit a form without a page reload, you must prevent the default browser submission behavior and use jQuery's AJAX method to send data asynchronously.

```javascript
$("#myForm").on("submit", function(e) {
    e.preventDefault();               // stop the normal page reload
    $.ajax({
        url: $(this).attr("action"),
        method: $(this).attr("method"),
        data: $(this).serialize(),
        success: function(response) {
            console.log("Server replied:", response);
        },
        error: function(xhr) {
            console.error("Request failed:", xhr);
        }
    });
});

```

This pattern captures form data, serializes it, and sends it to the server without refreshing the page.

## Server-Side Reception with Python Requests

On the server side, a Python web framework (such as Flask or Django) receives the AJAX request. The Requests library comes into play when you need to forward that data to another service or API.

```python
from flask import Flask, request, jsonify
import requests

app = Flask(__name__)

@app.route("/login", methods=["POST"])
def login():
    # Grab the form fields sent by jQuery

    form_data = request.form.to_dict()
    
    # Forward them to an authentication service using Requests

    auth_resp = requests.post(
        "https://auth.example.com/api/login",
        json=form_data,
        timeout=10,
    )
    auth_resp.raise_for_status()
    return jsonify(auth_resp.json())

```

In [`src/requests/api.py`](https://github.com/psf/requests/blob/main/src/requests/api.py), the `post()` function delegates to a `Session` object, which manages the HTTP lifecycle.

## Optimizing with Session Objects for Multiple Requests

When forwarding multiple AJAX submissions or maintaining persistent connections, use a `Session` object to reuse TCP connections and maintain cookies across requests.

```python
import requests

# Create a session that persists across function calls

session = requests.Session()
session.headers.update({"User-Agent": "my-app/1.0"})

def submit_form(url, payload):
    # Re-uses the same TCP connections and session state

    resp = session.post(url, data=payload, timeout=8)
    resp.raise_for_status()
    return resp.text

```

According to the source code in [`src/requests/sessions.py`](https://github.com/psf/requests/blob/main/src/requests/sessions.py), the `Session` class handles:
- **State management**: Cookies, headers, and authentication via `merge_setting` and `merge_hooks`
- **Request preparation**: Building `PreparedRequest` objects via `prepare_request`
- **Redirect resolution**: Following HTTP redirects through `resolve_redirects`
- **Adapter selection**: Routing requests to the appropriate transport via `get_adapter`

## Core Architecture: How Requests Processes HTTP

Understanding the internal flow helps debug AJAX integration issues. When `requests.post()` is called, the library executes this pipeline:

1. **Public API** ([`src/requests/api.py`](https://github.com/psf/requests/blob/main/src/requests/api.py)): Convenience functions like `get()`, `post()`, and `request()` create a temporary `Session` and delegate to it.

2. **Session Management** ([`src/requests/sessions.py`](https://github.com/psf/requests/blob/main/src/requests/sessions.py)): The `Session` object merges default settings with request parameters, creates a `Request` object, and prepares it into a `PreparedRequest`.

3. **Model Preparation** ([`src/requests/models.py`](https://github.com/psf/requests/blob/main/src/requests/models.py)): The `PreparedRequest` class normalizes the URL, encodes the body, and finalizes headers before transmission.

4. **Transport Adapters** ([`src/requests/adapters.py`](https://github.com/psf/requests/blob/main/src/requests/adapters.py)): The `HTTPAdapter` (default adapter) uses urllib3 to manage connection pools and send the prepared request over the wire.

5. **Utility Functions** ([`src/requests/utils.py`](https://github.com/psf/requests/blob/main/src/requests/utils.py)): Helper functions handle URL encoding, header parsing, cookie serialization, and proxy resolution.

6. **Exception Handling** ([`src/requests/exceptions.py`](https://github.com/psf/requests/blob/main/src/requests/exceptions.py)): Network errors, timeouts, and HTTP errors surface as specific exception classes like `ConnectionError` or `HTTPError`.

This architecture ensures that whether data originates from a jQuery AJAX call or another HTTP client, Requests handles it with consistent connection pooling, authentication, and error handling.

## Summary

- **jQuery AJAX** prevents page reloads by using `event.preventDefault()` and `$.ajax()` to send data asynchronously to a server endpoint.
- **Python Requests** operates on the server side to receive AJAX submissions or forward them to external APIs using `requests.post()` or persistent `Session` objects.
- **Session persistence** improves performance when handling multiple AJAX submissions by reusing TCP connections and maintaining state across requests, as implemented in [`src/requests/sessions.py`](https://github.com/psf/requests/blob/main/src/requests/sessions.py).
- **Core architecture** involves [`api.py`](https://github.com/psf/requests/blob/main/api.py) for entry points, [`sessions.py`](https://github.com/psf/requests/blob/main/sessions.py) for state management, [`models.py`](https://github.com/psf/requests/blob/main/models.py) for request preparation, and [`adapters.py`](https://github.com/psf/requests/blob/main/adapters.py) for transport handling.

## Frequently Asked Questions

### How do I handle file uploads from jQuery AJAX using Python Requests?

When submitting files via jQuery AJAX using `FormData`, the server receives multipart/form-data. To forward these files using Requests, open the file in binary mode and pass it to the `files` parameter:

```python
with open('uploaded_file.pdf', 'rb') as f:
    requests.post(
        "https://api.example.com/upload",
        files={"file": f},
        timeout=30
    )

```

### Can Python Requests maintain session cookies between jQuery AJAX calls?

Yes. While jQuery AJAX manages cookies in the browser, Python Requests uses the `Session` object to persist cookies across server-side requests. When forwarding AJAX data to other services, instantiate `requests.Session()` once and reuse it; the session automatically stores and sends cookies according to the target domain's responses, as handled in [`src/requests/sessions.py`](https://github.com/psf/requests/blob/main/src/requests/sessions.py).

### What is the difference between using `requests.post()` and a `Session` object?

`requests.post()` creates a new temporary `Session` for a single request, which is convenient for one-off calls but incurs connection setup overhead. A `Session` object, defined in [`src/requests/sessions.py`](https://github.com/psf/requests/blob/main/src/requests/sessions.py), maintains persistent connections via HTTP keep-alive, preserves cookies across requests, and allows default headers and authentication to be set once and reused. Use `Session` when handling multiple AJAX submissions or when connection pooling matters.

### How do I debug connection issues when forwarding jQuery AJAX data through Requests?

Enable debug logging to trace the request flow through the adapter layer in [`src/requests/adapters.py`](https://github.com/psf/requests/blob/main/src/requests/adapters.py). Configure logging before making the request:

```python
import logging
import requests

logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger("urllib3")

response = requests.post("https://api.example.com/endpoint", data=payload)

```

This outputs connection pool activity, SSL verification details, and raw HTTP headers, helping identify whether the issue originates from the jQuery AJAX client or the Requests server-side forwarding logic.