Debugging AJAX CORS preflight requests

Reponse for preflight has invalid HTTP status code 405

I’ve written a simple HTML5 game that uses JS to communicate with a server via AJAX. When I’ve done this previously I’ve always built an accompanying Rails server, so I’ve had no CORS issues. At my day job we host in the cloud and have people looking after the servers – from my end, they just work, I don’t need to think about how. But for my latest side project someone else built the server.

It’s a MS server built with something dot net and Java something or other. It doesn’t really matter to me, as we’ll communicate via JSON over AJAX. But I ran into problems as soon as I tried to communicate witht the server.

After a couple of little glitches getting the server configured I ran into an error which had me stumped for a while. It was an error in Chrome when it tried to make the AJAX request.

Reponse for preflight has invalid HTTP status code 405

Huh? WTF is a preflight?

It took me a while to dig into this, but it’s actually pretty simple. When a JavaScript app makes an AJAX CORS request from a server, the first thing is does is check with the server whether that’s allowed. It sends a little reqest saying who it is, and what it wants to do – that’s the preflight request.

If the preflight request is OK, the server responds back saying the request is allowed. The JS app then sends the actual request and everything is shiney.

My problem is that my preflight was getting a not allowed response. The simplest way to check is with a simple cURL request. To see a valid preflight response, run the following in a terminal (all on one line).

curl -H “Origin: http://example.com”
  -H “Access-Control-Request-Method: POST”
  -H “Access-Control-Request-Headers: X-Requested-With”
  -X OPTIONS –verbose
  https://www.googleapis.com/discovery/v1/apis?fields=

Thanks to monsur on Stack Overflow for the info.

You should get something back similar to:

➜  ~ curl -H “Origin: http://example.com” -H “Access-Control-Request-Method: POST” -H “Access-Control-Request-Headers: X-Requested-With” -X OPTIONS –verbose https://www.googleapis.com/discovery/v1/apis\?fields\=
   Trying 216.58.199.42…
 Connected to www.googleapis.com (216.58.199.42) port 443 (#0)
 TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
 Server certificate: .googleapis.com
 Server certificate: Google Internet Authority G2
 Server certificate: GeoTrust Global CA
> OPTIONS /discovery/v1/apis?fields= HTTP/1.1
> Host: www.googleapis.com
> User-Agent: curl/7.43.0
> Accept: /
> Origin: http://example.com
> Access-Control-Request-Method: POST
> Access-Control-Request-Headers: X-Requested-With
>
< HTTP/1.1 200 OK
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: Mon, 01 Jan 1990 00:00:00 GMT
< Date: Sat, 30 Apr 2016 03:24:25 GMT
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Headers: X-Requested-With
< Access-Control-Allow-Methods: DELETE,GET,HEAD,PATCH,POST,PUT
< Access-Control-Allow-Origin: http://example.com
< Access-Control-Max-Age: 3600
< Vary: Origin
< Vary: X-Origin
< Content-Type: application/octet-stream
< X-Content-Type-Options: nosniff
< X-Frame-Options: SAMEORIGIN
< X-XSS-Protection: 1; mode=block
< Content-Length: 0
< Server: GSE
< Alternate-Protocol: 443:quic
< Alt-Svc: quic=“:443”; ma=2592000; v=“33,32,31,30,29,28,27,26,25”
<
 Connection #0 to host www.googleapis.com left intact
➜  ~

The three most important response headers to look for are:

Access-Control-Allow-Headers
Access-Control-Allow-Methods
Access-Control-Allow-Origin

If you don’t have these three headers in the response, the server is misconfigured to respond to AJAX CORS requests. I just had to give the info to the server guy. He reconfigured the server to allow preflight requests, and we were all sorted out.

It’s a weird thing for me to do a side project with someone else running a server, but it’s a great learning experience sorting out cross domain issues!

Optimizing load times and UX for large HTML5 activities

Large HTML5 Games and Loading Complete Videos

I’m a Señor Front End Developer at Blake E-Learning, making kids educational games. These games are pretty heavy on multimedia assets, and tend to run for a few minutes each, usually starting with a video. One problem we need to deal with is load times – activities regularly load several meg of assets – and both kids and teachers can be a little impatient.

State of the Union

For a long time all game assets loaded before starting the game. Kids could spend a long time starting at load bars. We’ve recently changed thing with how we load games, and have seen some load times drop by over 90%!

Our games are set up as a Game with one or more GameState. Think of the Game as a book, and each GameState as a chapter. Often we only had one GameState per Game, but many had several GameStates. The first thing we did was change thing up to load assets per GameState.

By starting the game after loading assets for the first GameState, load times were immediately dropped for games with multiple states. This was easy to implement using LoadJS – part of theCreateJS Suite. Since PreloadJS lets you dynamically add content as you go, all we needed to do was define a mini asset manifest for each GameState and load them sequentially. If a state isn’t loaded by the time it’s reached, we simply throw up a quick load spinner.

Divide and Conquer

The next step was to divide long game states into seperate states. For example – if a character starts with a long speech before an interactive component starts, we’d seperate the speech into its own state. This way the interactive componenents could load while the character makes their speech.

Essesntially, we picked a reasonable bandwidth to throttle download to (we picked Good 3G speeds under Chrome network throttling), then sliced and diced activities so they streamed the activity in with minimal download for the first state. This worked brilliantly, with one exception…

HTML5 video full preload in javascript

A heap of activities start with a video. The problem is that videos HTML5 videos stream, notdownload. There’s no event emitted on download complete. Instead, the last event emitted iscanplaythrough, which happens when the browser compares how much is buffered with video length and download speed. When the browser calculates the video should be able to play though without glitching, it emits the canplaythrough event.

The problem is that as soon as a video can play though:

  • we play it
  • our state preloader starts to download assets for the next state
  • download slows as it keeps downloading the video, plus new assets
  • video playback glitches

So we came up with a workaround.

We swapped the Game to not start preloading assets if the first GameState is a video. We then emit a series of callbacks while the video is loading to check if it’s buffered all the way to the end. As soon as it is, we start preloading other assets. No more glitchy play.

checkLoaded: ( video ) ->
  if ( video.buffered.end(0) > video.duration - 0.05 )
    @game.preloadAssets()
  else
    window.setTimeout( ( => @checkLoaded( video ) ), 0.1 )

The results are in

We still have some work to do – with asset optimisation and audio sprites being next in line – but we’ve made a heap of improvements to the user experience. The “worst” cut around 30% of the time to activity start. The best activity start time improved 92% – from 13.3 seconds down to 1.1 seconds! Nice save.

Magic number roundificator limits significant decimal places in text

Limit decimal places in a text string

I have put no validation, or tests, in here. It was a simple proof of concept, but I thought someone may find it useful. All it does is go through the text you paste in the top field, look for numbers resembling 12.3456, and round it to the selected number of decimal places.

Note this leaves elements surrounding floating numbers alone. So:

;=as1234.56984985k(92.2898293;kjnand

parses as

;=as1234.56k(92.29;kjnand

Paste JSON / text:

Round to:

decimal places.

Roundified:

Background

I was looking for a script today to find all the Floats in a long text file, and round them all to a set number of significant digits. I couldn’t find one, so I wrote a quick page. I’ve put it up in case it’s of use to anyone else.

We use Dragon Bones a lot a work, and today one of the animators came up with a 720kb JSON animation file (it’s a super long animation with a lot going on). I was looking at ways to optimise it. There were some strings which were repeated and redundant, and some long floating numbers.

In my experience with SVGs, and other visual elements, I find that floats rarely need more than 1 or 2 digits after the decimal place. So I wrote a quick script to round all the numbers to 2 decimal places. It worked fine for our use case, I’m going to write something to put into the build process for the animation files, but here’s the proof of concept.

Note that there are a lot of other things that can be done to optimise a large Dragon Bones file, but that’s are pretty specific use case, so I provided a more general case here.