Access-Control-Allow-Google

Quick tangent this week, then back to the puppet show!

We launched a website this past week.  I’d love to say we were able to use all the cool new deployment tools, but for various reasons (stack choice, database connectors, developing and deploying on Windows, major version and architecture updates), it just wasn’t possible.  So, we had to shut down the old server, remotely log in, make some upgrades and update some versions, cross our fingers, and re-start.

Always a risky procedure.  Particularly with a two person team.  Really a one and a half person team.  I do a bit of dev ops, but am mostly a Javascript guy.  Apache config files aren’t really my sweet spot.

My partner on this was updating Django versions, then trying to install the right db connector to work with SqlServer.  It was tricky, but eventually he got there.  I updated Node, built our Angular application, and deployed the front end server.  For the most part, it worked, but there were a few ‘gotchas’.

One involved enabling https.  This was something we didn’t test in development- we have one SSL certificate and it was in use for the production site.  Enabling it on the Express server was simple enough, but I didn’t realize that there were 3 important parts.  The key, the certificate (got both those), and the chain.  Most modern browsers only need the first two, but some require the chain (I’m looking at you, Firefox on Mac).  The chain needs to be split on newlines in Node to work.  But we got past that hurdle after a bit of frantic Googling.

The other interesting one involved server side rendering our Angular application.  Like most modern JS apps, ours uses some 3rd party libraries.  We could never get Angular’s built in SSR to work (though we are still trying), so we’re using a 3rd party service to do the render.  Our server contacts that 3rd party’s servers, gets the rendered version of a page, and returns it (and then the SPA loads and takes over).  Google’s spiders are happy.  But our users aren’t- they just had to wait over 2 seconds to get a page.  However, we can store those renders in a local cache, so on any subsequent visit, it’s blazing fast again (I’m documenting the crawl and storing of those in the Puppeteer series- see entry one from last week- it’s super fun!).

Back to the related launch issue: we were getting cross origin request errors.  But only if the url included ‘www’.  For example: if I went to domain.tld, our site loaded, it made a delayed https call to our internal news article api, loaded those, and everything was great.  But if I went to http://www.domain.tld, boom- CORS error.  The error referenced a disallowed header.

The lesson this reinforced was to use your dev tools.  I hit F12 and checked the network tab.  Clicked the red response and inspected the request and response headers.  Then I made a successful (no ‘www’) request and compared those.  The ‘www’ request was getting an extra header related to the prerendering service (still not sure why it wasn’t present on all requests).  So, on our Apache server (running the news API- which just returns JSON), we just had to add that header to the allowed list.  I definitely don’t have that command memorized, but once I knew exactly what I was Googling for, it took about 2 minutes to find and implement.

Use your dev tools.  Words to live by in this business.  When something doesn’t work, there’s always an answer- particularly in this world where everything is online.  Dev tools help narrow down that search.  I went from a panic search of “site works without ‘www’ but not with ‘www'” to “apache configuration allow headers”.  The first got me nothing useful.  The second solve my problem almost immediately.

 

Advertisements

We are Willing to Learn

Great stuff.  If you’ve never seen Stripes, do yourself a favor and watch it this weekend.  Or now.

“No we’re not, but we are willing to learn.”  A great sentiment.  I listened to a great podcast the other day.  It’s called the Front End Happy Hour and it combines two of my favorite things- programming and drinking.  Anyway, they were discussing ES6 and all the cool new features.  The discussion went to knowledge and training- something I’ve found interesting lately.

With the internet at our fingertips, most info is available in seconds.  So the memorization of methods and syntax becomes far less important than 2 main factors.  1) How to apply that info, and 2) The willingness to keep learning about new info.

#1 speaks to the difference between copy/pasting some snippet of code off Stack Overflow into your app/site versus taking the time to understand how said snippet works, why you’d want to use it, and what the possible alternatives are.  You can get away with the blind copy/paste for a bit, but eventually, you’re going to have to know how it works- or know enough to recognize that an accepted answer might not work for your use case.  A personal example is regex – the few times I’ve had to write one, I’ve had to look up the syntax (thanks MDN!).  Every time- I’ve just never memorized that aspect of my job.  And it wouldn’t really make much sense to- it’s readily available and I know the basics of how the regex works and when/where to apply it (I know- the answer is ‘never’!).  Or some of the built in methods for manipulating strings – sometimes I’m writing JS, sometimes Python, sometimes C# and the call is different in each.  I’ll forget and type the wrong one, then do a quick search for the correct syntax.

#2 is what they discussed on FEHH.  It seems like every week there are new frameworks or tools to use in frontend dev.  Or the next ECMAscript release is bringing new tools.  Or there’s a new way of doing a task that you just have to know to stay current.  The willingness to learn new things becomes very important in a rapidly changing industry.  The panelists on the podcast had some really great things to say on the topic.

To bring it full circle, we come to imposter syndrome.  That heavily used term meaning that you feel like you don’t belong in the position you’re in.  I like to say I have imposter syndrome because I am, in fact, an imposter.

And it’s true- I don’t have a CS degree.  I’m not accredited by any governing body to code your Angular app or hook it up to a database.  I started learning this stuff because a job allowed it and I found it interesting.  So yes- I have to Google a lot of things during my day (point 1 above).  Why?  Because I’m still learning.  Every day.  And yes- this can lead to the feeling that I don’t really know what I’m doing.  That I’m an imposter.  But maybe the best way to combat that is to remember point #2 above.  We’re all still learning this stuff.  When you look something up and feel like you don’t really know it, dig deeper and learn about it.

Mostly incoherent ramblings, but if you take one thing away, take the link to Front End Happy Hour – it’s a good listen!

Things to Remember

Still really liking Django (and by extension, Python).  Some things are a bit tricky to figure out, but overall, it’s really easy to use and can be a very powerful tool for developing on the web.

Deploying to a live server can be one of those tricky areas.  Django makes it super easy to build locally, including a server with it’s package.  However, eventually, you’ll want to put your creation somewhere on that world wide part of the web.  The project I’m working on already had a server available, so I FTP’d all the files to the right directory, remote logged in, hit my manage.py runserver command, and opened my browser to check it out.

And saw a debugging error telling me there was an invalid object.  I’d become somewhat familiar with the error messages Django throws during the initial development, but this one had me stumped.  I checked the schema- all looked right.  I double checked my models and they looked fine.  I’d even installed South (the project requires Django 1.6- don’t ask me why), but it couldn’t find any issues.

Then I realized that I’d tested this all locally, but never actually run an initial migration on the remote server.  The error was telling me there was an invalid object because the view was trying to access an object that simply hadn’t been initialized.  I ran a syncdb command on the remote server and everything started working!

So, I guess the moral is to try not to forget those first steps.  I hadn’t really checked anything locally when first setting up the project- I hadn’t opened the site in a browser into quite a way into the initial process, so hadn’t seen this issue.  I went back and typed out a startup guide so I wouldn’t forget.  Eventually, I’ll remember these things automatically, but for the meantime, it’s always good to have a backup.

:First!

The DOM Tree Of Life!
The DOM Tree Of Life!

One problem (of many) I ran into while adding validation checks on our request form feature was limited to IE8.  The code worked great in other browsers- my function used find() to get the correct error notice wrapper to display and switched it on if a field was blank or otherwise invalid.  But not in IE8.

In that world, the function would show the error notice wrapper for every field.  I made a little progress by fixing my PHP code- it originally inserted an error wrapper on each form field- even ones that weren’t required.  I figured it didn’t matter, as they’re all ‘display: none’ by default, but my first step was to add a conditional to my PHP to ensure that error wrappers only appear attached to required form fields.

That didn’t solve the problem- though at least it reduced the amount of red I saw on my test form.

Still- anytime a form was submitted with any unfilled (but required) field, any required field below that in the form was marked as invalid (even if it had a valid value).  Only in IE8.

The answer was to use the :first selector (https://api.jquery.com/first-selector/).  It looks like IE9 and later (and all other browsers) will stop at the first instance when using find(), but 8 will not- it will get all matches.  However, when I added the :first selector to my function that processed each error, 8 fell into line with the rest of them.  It stopped popping error messages all the way down the tree.

Another example of the notion that development can go so well for the majority of a project, and one little problem can stall for way too long.  Should I have thought of the :first selector earlier?  Probably, but because the code worked everywhere else, it was a bit of a head-scratcher for me.

Hope this helps anyone with a similar issue.  Actually- what I really hope is that everyone drops support for IE8 and no one has to read about this!