CORS and cross-origin HTTP requests

It seems that you have already known quite a few about HTTP request and CORS. But there is always something to learn when you look closer

CORS is short for Cross-Origin Resource Sharing. As the word shows, it gives web servers cross-domain access controls over either static or dynamic data. For static data sharing, its typical type of how CDN works. In essence, it adds new HTTP headers that allow servers to describe the set of origins that are permitted to read that information using a web browser. This is the basic background knowledge.

An interesting note about these requests is there are types of “preflighted” ones. The cause of this is many HTTP methods could have side-effects on server’s data. In order to prevent actual data impact, a more elegant solution would be mandating the browser “preflight” the request to get “approval” from the server first by an HTTP OPTIONS request, then sending the actual request with actual HTTP request.

There are conditions to trigger a CORS preflight, falling any of below 3 conditions will need a preflighted request. Otherwise, a simple request will be sufficient to achieve the goal.

  1. Request uses methods other than following

    • GET
    • POST
    • HEAD
  2. Request includes any below headers
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type (but note the additional requirements below)
    • DPR
    • Downlink
    • Save-Data
    • Viewport-Width
    • Width
  3. If the Content-Type header has a value other than the following
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain

Below is the illustration of how requests are done between client and server.

Here is the full exchange headers info for a preflight request. First is the preflight request.

Second is the actual request for resource.

PostCSS learning summary

PostCSS is a tool for transforming styles with JS plugins. These plugins can lint your CSS, support variables and mixins, transpile future CSS syntax, inline images, and more

This post is a bit long overdue. I try to keep up with what I have explored with PostCSS, which so far is absolutely elegant, fun, well-structured solution to frontend CSS.

In technical, it supports gulp, webpack and npm/cli run. Since webpack is most popular among the community at the moment, so sample as below,

module.exports = {
    module: {
        loaders: [
            {
                test:   /\.css$/,
                loader: "style-loader!css-loader!postcss-loader"
            }
        ]
    },
    postcss: function () {
        return [require('autoprefixer'), require('cssnext')];
    }
}

After setting up, there are several few key points of PostCSS features worth covering, it includes,

  1. Autoprefixer
  2. CSSnext
  3. CSS Modules
  4. Stylelint
  5. PreCSS

Almighty Sublime 3 plugins

To begin with, here is the code snippet to install sublime Package Control. (sublime text 3)


After the installation, the fun part begins.

  1. Javascript Beautify – This makes the javascript code tidy and neat, to suit the code standard. Using ctrl+alt+f
  2. Javascript Patterns – This incredibly increase your speed of coding in javascript. More juicy details in below
  3. HTMLBeautify – This prettify the HTML code using ctrl+alt+shift+f
  4. PHPDoc – This provides convenient way of writing php code coments

About Javascript Patterns

  • trigger: ifun
    ;(function() {
        'use strict';
        // closure scope
    }());
    
  • trigger: forin
    for (var prop in obj) {
        if (obj.hasOwnProperty(prop)) {
            obj[prop];
        }
    }
    
  • trigger: ifor
    for (i = 0, len = arr.length; i & lt; len; i++) {
        // array length is calculated only 1 time and then stored
    }
    
  • trigger: constructor
    var ConstructorName = (function() {
        'use strict';
    
        function ConstructorName(arg1, arg2) {
            // enforces new
            if (!(this instanceof ConstructorName)) {
                return new ConstructorName();
            }
            // constructor body
        }
    
        ConstructorName.prototype.someMethod = function(arg) {
            // method body
        }
    
        return ConstructorName;
    
    }());
    
  • trigger: singleton
    var singletonName = (function() {
        'use strict';
        var instance;
    
        singletonName = function() {
            if (instance) {
                return instance;
            }
    
            instance = this;
    
            // your code goes here
        };
    
        return singletonName;
    
    }());
    
  • trigger: module
    var moduleName = (function() {
        'use strict';
        var privateVar = '';
    
        var moduleName = {
            init: {
                // kickoff
            }
        }
    
        return moduleName;
    
    }());
    
  • trigger: rmodule
    var revealingModule = (function() {
        'use strict';
        var privateVar = 'foo';
        var publicVar = 'bar';
    
        function privateFunction() {}
    
        function publicFunction() {}
    
        return {
            publicVar: publicVar,
            publicFunction: publicFunction
        };
    }());
    
  • trigger: Memoization
    var expensiveFunction = (function() {
        'use strict';
        var funcMemoized = function() {
            var cacheKey = JSON.stringify(Array.prototype.slice.call(arguments));
            var result;
    
            if (!funcMemoized.cache[cacheKey]) {
                // your expensive computation goes here
                funcMemoized.cache[cacheKey] = result;
            }
    
            return funcMemoized.cache[cacheKey];
        }
    
        funcMemoized.cache = {};
    
        return funcMemoized;
    }());
    
  • trigger: Throttle
    var onResize = (function() {
        'use strict';
        var timeWindow = 200; // time in ms
        var lastExecution = new Date((new Date()).getTime() - timeWindow);
    
        var onResize = function(args) {
            // your code goes here
        };
    
        return function() {
            if ((lastExecution.getTime() + timeWindow) & lt; = (new Date()).getTime()) {
                lastExecution = new Date();
                return onResize.apply(this, arguments);
            }
        };
    }());
    
  • trigger: Debounce
    var autocomplete = (function() {
        'use strict';
        var timeWindow = 500; // time in ms
        var timeout;
    
        var autocomplete = function(arg1, arg2) {
            // your code goes here
        };
    
        return function() {
            var context = this;
            var args = arguments;
            clearTimeout(timeout);
            timeout = setTimeout(function() {
                autocomplete.apply(context, args);
            }, timeWindow);
        };
    }());
    
  • trigger: namespace
    (function(namespace) {
        'use strict';
        // your code goes here
        namespace.method = function() {};
    })(window.namespace = window.namespace || {});