Ah, 2017. Feels like a different era in web stuff, doesn’t it? I remember I was tinkering with this personal project, a little dashboard thingy. Nothing too crazy, but I really wanted to make parts of it update without that annoying full page reload. You know, make it feel a bit more snappy, a bit more “modern” for back then.

So, everyone was talking about Ajax. Ajax this, Ajax that. Sounded like some kind of cleaning product to me at first, not gonna lie. But yeah, Asynchronous JavaScript and XML. The XML part was already getting a bit old even then, most folks were using JSON, which made way more sense to my brain.
Getting started was a trip. I remember diving into it with plain old JavaScript. jQuery was still king for many, and yeah, it made Ajax easier, but I was stubborn. I wanted to understand what was happening under the hood. Or maybe I was just being cheap and didn’t want to add another library for this one thing. Probably a bit of both.
My First Tango with XMLHttpRequest
So, the first hurdle was this thing called `XMLHttpRequest`. What a mouthful, right? I had to create an instance of it:
var xhr = new XMLHttpRequest();
Simple enough, I thought.
Then came the whole `onreadystatechange` adventure. This was a function that would fire off, like, multiple times as the request went through its stages. I had to check for `* === 4` (which meant the operation was complete) and `* === 200` (which meant ‘OK! All good!’). If I missed one of these, or got the numbers wrong, stuff just wouldn’t work, or I’d get weird errors. It felt like defusing a bomb with a cheat sheet.
Opening the request was next: *('GET', '*', true);
. The ‘GET’ part was for fetching data. Sometimes I needed ‘POST’ if I was sending something to the server. That ‘true’ at the end, that was important – it meant asynchronous. If I set it to ‘false’, the whole browser would freeze until the server responded. Learned that the hard way, of course. My browser just locked up, and I was like, “What did I do?!”

Then, . And wait. And hope.
When the response finally came back, assuming I got the `readyState` and `status` checks right, I had to parse it. If it was JSON, it was something like . If the JSON was messed up, well, more errors. Fun times.
The Stumbling Blocks of 2017
It wasn’t all smooth sailing, oh no. There were plenty of things that made me want to pull my hair out.
- CORS errors! Oh man, Cross-Origin Resource Sharing. If my little script was on `localhost:8000` and trying to fetch from a different port or a different domain (even a subdomain sometimes!), the browser would just scream “NOPE!” in the console. Figuring out server-side headers like `Access-Control-Allow-Origin` was a whole other battle.
- Callback hell. Seriously. You’d have a callback for the Ajax response, and inside that, maybe you’d do something else that needed another callback. It got messy fast. My code started looking like a pyramid tilted on its side.
- Error handling. What if the server was down? What if it sent back a 500 error? I had to actually think about that and show a nice message to the user, not just let the whole thing crash and burn.
I remember this one time, I was working on a small feature for a friend’s photography portfolio. He wanted a “load more” button for his gallery. Seemed simple. But making that Ajax request, getting the next batch of images, and then smoothly adding them to the page without breaking the layout… that took me an entire weekend. My kitchen table was covered in coffee cups and scribbled notes. I think I dreamt in JavaScript error messages that Sunday night. It was just a small thing, but getting it to work felt like a huge win.
Why do I remember this so vividly? Well, that particular weekend, my internet was super flaky. Kept cutting out. So, testing this Ajax thing, which relies on, you know, an internet connection to the server (even if it was just `localhost` for the backend part), was extra painful. Every time it failed, I didn’t know if it was my code or my terrible ISP. Good times, character building, they say.

Eventually, I got the hang of it. That little “loading…” message would appear, then poof! New content, no refresh. It felt like magic. Like I’d unlocked a new superpower. It wasn’t always pretty, my early Ajax code was probably a horror show to look back on, but it worked.
Looking back from now, with things like the `fetch` API and libraries/frameworks like Axios, Vue, React that handle so much of this complexity for you, it’s almost funny. `fetch` especially made things cleaner with Promises. But slogging through `XMLHttpRequest` back in 2017, that really taught me the fundamentals. And I guess there’s some value in that, even if it was a bit painful at the time. Made me appreciate the tools we have now a whole lot more!