Devember 2016 – Day 8 and 9 – Chrome Caches AJAX Response

I didn’t blog yesterday here, but I did tweet, and I did write code.  It was late, but I still got stuff done.

Today was an interesting day.  I’m still coding, but I came across an interesting bug I’d like to share.

So, in the code I have now, depending on the request’s Accept header, it will return either HTML or JSON.  It’s the same endpoint, but depending on the request made, it will return different results.  The result is the same information, just presented differently.  One way for humans, another for computers.

Now, in Firefox and Safari, this works just fine.  If you go to the page, everything loads up as you’d expect.  If you go back in the browser, and then go forward again, the page that is displayed is the same page you’d expect to see.  The HTML result.

But in Chrome, it doesn’t work like this.  Here is what happens in my case.

First, you make a request to a page /foo/bar.  This request has a header entry:

Accept: text/html

The page loads an HTML page which has JavaScript.  This JavaScript makes a request to the same page /foo/bar, except this time, the Accept header is different.

Accept: application/json

In this case, it’s the same URL, but different requests.  This second request returns JSON as expected.

Now, you click the Back button, and go back a page.  Then you click the Forward button, and instead of seeing the HTML page as you’d expect, you see the JSON result.

Now, even though Chrome has this bug, you can work around it.  When you return the JSON response, you can just send back a response that includes the following headers.

Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Expires: Thu, 18 Nov 1971 01:00:00 GMT

This will prevent the AJAX response from being cached, meaning the last cached item will be the HTML page.

How else can you use this?

So, in thinking about this, I was wondering how else I could use this.  After all, if I make a request to the same URL behind the scene and cache it, I can change what’s cached in the browser.  Is there ever a case where you’d want to change what was cached without showing the user right away? I don’t know.  But it’s interesting.  And it would only work on Chrome.

Devember 2016 – Day 5

Another day has gone by.  Another video.  And more code. I learned that the recordings are difficult or impossible to see on screens smaller than an ultrawide, so this means they are mostly useless.  I need to come up with a solution to that if I mean to keep streaming.

From my commit:

So, didn't really think about it before, but decided to add
configuration injection into our commands.  This seems to have worked
out well and I'm happy with the results.  The command defines the
configuration and where it expects it, and the application provides the
external configuration in the appropriate location and it automatically
gets injected.

We also now can display route details.  This still needs more work, but
we are doing well and progressing.

Devember 2016 – Day 4

Day four is done. Got the UI up today, though it’s very basic.  Decided that the API builder should, obviously, not worry about HTML output.  It should be focused on outputting results as if it’s an API, not acting as a template.  That being said, nothing prevents that from happening.  HTTP is, effectively, and API.  But the focus is on data in a format like JSON.

I streamed it once again so you can follow along with the thought process.

I think tomorrow I’ll continue with the UI, building out a system that allows you to compose commands together.

Devember 2016 – Day 3

Day three is done. Not much done today.  Cleanup and work on the output functionality.  I streamed it once again so you can follow along with the thought process.

Added a TODO.md file, which I think is handy in terms of keeping track of my thoughts, on what has been done, and what needs to be done.  I think tomorrow I’m going to work a bit on a UI that is built using this system.  Still not sure of a name.  Still, three days down.  Let’s keep it going.

Devember 2016 – Day 2

Day two is complete. Continued work on the stuff I was doing yesterday.  Streamed it live to no one. That’s fine.  Overall, I’m happy with the progress I’ve made tonight.  Handled outputs, both from defining the API along with the context of the request.

I think tomorrow I might want to tackle parallel commands.  So, if I wanted to fetch multiple pieces of data at once, I could do that.  Maybe I can do something more real tomorrow, such as have something that requests someones Twitter and GitHub feed at the same time.  I could do that.

Devember 2016 – Day 1

Day one is complete. I’m working on something completely different, but it’s started.

I want to build a system where APIs can be built using Node.js in a way that allows you to piece together different methods.  I realize there are systems out there like this, but I couldn’t find anything that meets my goals.  Besides, I wanted to build it.  Today was a longer day.  More than an hour, mostly because I didn’t want to leave it in a half state.  I can continue tomorrow where I left off with a working system and clear next steps.

I live streamed the entire session using Twitch.  There was one point where I was dealing with an error that I could not figure out.  Here is the moment I discover the very simple error. At some level, it’s fairly embarrassing to have that live on video.  But things like that do happen.

Most of this is being designed as I go along.  I’m not so concerned about performance at the moment.  Mostly it’s about getting it working.

Devember 2016

I, Jason Lotito, will participate to the next Devember. My Devember will be programming a game. I promise I will program for my Devember for at least an hour, every day of the next December. I will also write a daily public devlog and will make the produced code publicly available on the internet. No matter what, I will keep my promise.

My goal is simple.  I’m mostly following along with Handmade Hero and I’d like to continue on through the month.  I might do other things, and I’ll update that as I go along.  The goal is to get back in the habit of coding nightly and learn new things as I do it.

  1. Day 1

Scripts in Confluence are an anti-pattern

Scripts in Confluence are an anti-pattern.

If you are going to take the time to document something out, then make an effort to take the time to script it out.  Even better, add it to something like Jenkins or Rundeck.  Maybe automate it.

This is true even if you have a list of steps in your documentation.  Run step 1, then step 2, then check for this, and if it’s true, do step 3, otherwise continue to step 4.  You are literally writing the program in English.

Scripts in Confluence are an anti-pattern. It’s not documented, it’s lazy.