# Sending Data Without a Page Reload: jQuery and AJAX

> The 2014 standard for decoupling form submissions from full page loads: practical usage of jQuery's $.ajax method.

- Published: 2014-05-04
- Category: Interface
- Tags: JavaScript, jQuery
- Reading time: 3 min read
- Source: https://www.muhammetsafak.com.tr/en/blog/sending-data-without-page-reload-jquery-ajax/
- Language: en-US
- Author: Muhammet Şafak

---
Until a few months ago, having the page reload every time a user submitted a form was perfectly normal to me. The user clicks the button, the page flickers, and the same page comes back with a different message. It worked — but it felt rough.

**AJAX (Asynchronous JavaScript and XML)** is a technique that lets the browser send a request to the server and receive a response without reloading the page. JSON has largely replaced XML in practice, but the name stuck. (How the language itself later made this kind of work easier is something I covered in [getting started with ES6](/en/blog/getting-started-with-es6-let-const-and-arrow-functions/).) jQuery's `$.ajax` method was the most widely used way to do this in 2014.

## Why jQuery?

JavaScript's built-in `XMLHttpRequest` object can handle AJAX, but you end up dealing with browser inconsistencies by hand. jQuery abstracts all of that complexity and behaves the same way across every browser. Every project I looked at back then had jQuery; there was no reason to learn anything else in that environment.

## Basic $.ajax usage

```javascript
$.ajax({
    url: '/api/yorum-ekle',
    method: 'POST',
    data: {
        yorum: 'Bu içerik çok faydalıydı.',
        makale_id: 42
    },
    success: function(yanit) {
        console.log('Başarılı:', yanit);
    },
    error: function(xhr, durum, hata) {
        console.log('Hata:', hata);
    }
});
```

`url` is the destination address, `method` is the HTTP verb, and `data` holds the payload. The `success` and `error` callbacks fire based on the server's response.

## Wiring a form submission to AJAX

The scenario I used most often in practice: the user fills out a form and submits it, the operation completes without a page reload, and a message is displayed to the user.

HTML side:

```html
<form id="yorumFormu">
    <textarea name="yorum" id="yorumAlani"></textarea>
    <button type="submit">Gönder</button>
</form>
<div id="mesaj"></div>
```

JavaScript side:

```javascript
$('#yorumFormu').on('submit', function(e) {
    e.preventDefault(); // Prevent the page from reloading

    var yorum = $('#yorumAlani').val();

    $.ajax({
        url: '/yorum-ekle',
        method: 'POST',
        data: { yorum: yorum },
        dataType: 'json',
        success: function(yanit) {
            if (yanit.basarili) {
                $('#mesaj').text('Yorumunuz eklendi.').show();
                $('#yorumAlani').val('');
            }
        },
        error: function() {
            $('#mesaj').text('Bir hata oluştu, tekrar deneyin.').show();
        }
    });
});
```

The `e.preventDefault()` line is critical — without it, the browser submits the form normally and the page reloads.

## Server side

On the PHP side, receiving the request and returning JSON is all you need:

```php
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $yorum = trim(isset($_POST['yorum']) ? $_POST['yorum'] : '');

    if (!empty($yorum)) {
        // Save to database...
        echo json_encode(['basarili' => true]);
    } else {
        echo json_encode(['basarili' => false, 'mesaj' => 'Yorum boş olamaz.']);
    }
    exit;
}
```

Setting the `Content-Type` header to `application/json` is good practice:

```php
header('Content-Type: application/json');
```

Forgetting this header won't cause an outright failure, but browsers and client libraries rely on it to process the response correctly. In particular, jQuery's `dataType: 'json'` option should be consistent with this header — mismatches can be confusing to debug.

## $.get and $.post shortcuts

There are shortcuts for the most common HTTP verbs:

```javascript
// GET request
$.get('/api/makaleler', function(yanit) {
    console.log(yanit);
});

// POST request
$.post('/api/yorum-ekle', { yorum: 'Merhaba' }, function(yanit) {
    console.log(yanit);
});
```

These are shorthands for `$.ajax`. They are convenient for simple cases, but when you need error handling, `$.ajax` gives you more flexibility.

## Loading indicator

It is good practice to let the user know that a request is in progress:

```javascript
$.ajax({
    url: '/api/veri',
    beforeSend: function() {
        $('#yukleniyor').show();
    },
    complete: function() {
        $('#yukleniyor').hide();
    },
    success: function(yanit) {
        // handle response
    }
});
```

`beforeSend` fires before the request starts; `complete` fires when the request finishes, whether it succeeded or failed.

One trap to avoid: hiding the indicator inside `success` instead of `complete`. If the server returns an error, `success` never runs and the spinner stays on screen forever. Because `complete` always fires, that is the right place to put the cleanup.

## Security: CSRF protection

A topic that often gets skipped with AJAX requests: CSRF (Cross-Site Request Forgery) protection. If you are using Laravel or another framework on the PHP side, POST requests typically require a token to be validated.

You need to send the token from the meta tag in your HTML along with every AJAX request:

```html
<meta name="csrf-token" content="<?php echo csrf_token(); ?>">
```

```javascript
$.ajaxSetup({
    data: {
        _token: $('meta[name="csrf-token"]').attr('content')
    }
});
```

Once you define this with `$.ajaxSetup`, every subsequent `$.ajax` call automatically includes the field. A POST request sent without the token makes Laravel throw a `TokenMismatchException` — figuring out why can take a while the first time.

## What I've learned so far

Building an interface that works without page reloads made a noticeable difference to the user experience. When I first implemented it, I had that "this is it" moment; the page no longer flickering seems like a small detail, but the improvement is significant.

jQuery made this easy, but understanding what is happening underneath matters too. To really appreciate the abstraction sitting on top of `XMLHttpRequest`, it is worth trying to write one by hand. Once you have done that, it becomes much clearer why jQuery became so widespread.

The hardest part of learning AJAX for me was shifting my mental model — treating the response as an event rather than a value. Instead of "fetch this data, then do that," you have to think "when this request completes, run this function." For someone coming from PHP, that mindset shift takes time: PHP executes line by line, each statement waiting for the previous one to finish. JavaScript, by contrast, says "call me when it's ready" and moves on. Once you internalize that difference, the reason `success` callbacks are structured the way they are becomes much clearer.
