Posts Tagged: Javascript

When JavaScript was first introduced, I dismissed it as being not worth my attention. Much later, I took another look at it and discovered that hidden in the browser was an excellent programming language. My initial attitudes were based on the initial positioning of JavaScript by Sun and Netscape. They made many misstatements about JavaScript in order to avoid positioning JavaScript as a competitor to Java. Those misstatements continue to echo in the scores of badly written JavaScript books aimed at the dummies and amateurs market.

Unbound methods in JavaScript

In my previous blog post I described technique how to avoid context object exposure in Observer pattern.

publish: function (publication) {
    for (var i = 0, len = subscribers.length; i < len; i++) {
        subscribers[i].call(undefined, publication); //hide context by specifying undefined as new execution context
    }
}

But foo.call(undefined, ...) may lead to assumption that context (this keyword) of the foo function will be equal to undefined. Well, it is not exactly true. this will be resolved to global window object.

function foo(){
    document.write(Object.prototype.toString.call(this)); //[object global]
}
foo.call(undefined);

But if the engine is running on strict mode, then this will be resolved as expected — to the exact thing it was applied to:

"use strict"
function foo(){
    document.write(Object.prototype.toString.call(this)); //[object Undefined]
}
foo.call(undefined);

Be careful with your assumption, especially in JavaScript!

Read more!

Third-party JavaScript API security

Third-party JavaScript is a pattern of JavaScript programming that enables the creation of highly distributable web applications. Many websites (publishers) embed untrusted JavaScript code into their pages in order to provide advertisements, social integration, user’s analytics and so on. Since JavaScript may change look and feel of the contained page, steal cookies or force user to visit some page – it should be considered as untrusted code which may harm not only the page, but also other third-party API’s on the same page. From third-party API developer point of view, publisher’s page became untrusted as well. Developer doesn’t know what publisher’s real intentions are and how other third-party JavaScript will behave.

So it is essential to protect third-party API from another untrusted code which could be present on the page.  While third-party code may be isolated in iFrame, this reduces performance and restricts communication between the hosting page and third-party code. Therefore a lot of APIs distributed via pure JavaScript injection into publisher’s page.

Anonymous wrappers

Anonymous wrapper allows to avoid global object pollution. In addition, if you pass some frequent-accessed global variables as parameters – it may lead to smaller size of minified JavaScript file. This is because minifier will consider argument named window (in the example below) as variable, but not as a keyword. So all references to window argument in function body will be replaced with something shorter.

(function(window){

//a lot of references to window object here

})(window)

But is it a safe way to write third-party code? Not really, it could be easily spoofed by another, untrusted JavaScript if it is executed before yours. The more bulletproof approach would be to use keyword this in global context. Also it is a good technique to rely on JavaScript default behavior regarding arguments – if argument is missed it will be assigned to undefined internally! So, here is an example with anonymous wrapper which guarantee you correct references to window and undefined objects.

(function(window, undefined){

//here we definitely can trust those two variables

})(this)
Read more!

Bitwise NOT in Javascript

isNumber Function

Even if I used some best-ever-practice in one of my projects, it doesn’t mean I can’t find even-better-approach in the next one. In other words there is always a place for learning.

Let’s take a look into simple function named isNumber

function isNumber(n){
     return typeof n === “number” && !isNaN(n) && n !== Infinity;
}

(to be honest, not the best approach, but it does its job)

Now, let’s try to improve/optimize this method by using bitwise not operation (~). For those who not familiar with such operation: ~ (bitwise not) operator will take its operand, convert it 32-bit integer and will invert each bit.

00000000000000000000000100111010


becomes

11111111111111111111111011000101


The same effect could be achieved by the following formula: – ( foo + 1 ). So, if ~foo = – ( foo + 1 ), then double bitwise operation will lead to ~~foo = – ( – ( foo + 1 ) + 1 ) = – ( –foo – 1 + 1 ) = foo. But please remember that foo will be converted to 32-bit integer internally.

Read more!

Relative URL and HTTPS protocol

All of you are familiar with such browser warning message:

image

This usually happens when you load the page via HTTPS protocol, but some of the page’s resources were requested by HTTP protocol. It’s not an option to simply disable warning in a browser, because such references create vulnerabilities that put the privacy and integrity of an otherwise-secure page at risk. It could be achieved by modifying insecure content in transit. In addition, regular internet users could be scared by such message and leave the page.

Client Side Protocol Detection

This is why web developers should take care of the issue by following next rule: within HTTPS page never include a reference to HTTP-delivered resource. But things became more complicated with pages which could be accessed by HTTP or by HTTPS. In this case you don’t know in advance what protocol to use. Another good example is to have some widget, which could be included in third-party pages and some of them are secure while others – not. Google Analytics team solved this problem by the following JavaScript snippet:

<script type="text/javascript"> 
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); 
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E")); 
</script>

The script analyzes what protocol is used on a current page and creates URL to Google Analytics script by using the same protocol (in addition it changes subdomain, but it is not a topic of discussion).

Read more!

When cached items became invalid?

There are a number of reasons why browser could make a conditional or unconditional request for item that is already in the cache.

Item is expired

The cached data is no longer fresh according to Cache-Control or Expires.

These specify the “freshness lifetime” of a resource, that is, the time period during which the browser can use the cached resource without checking to see if a new version is available from the web server. They are “strong caching headers” that apply unconditionally; that is, once they’re set and the resource is downloaded, the browser will not issue any GET requests for the resource until the expiry date or maximum age is reached.

Browser applied its heuristic and decided that item should be revalidated by server based on

Last-Modified and ETag. These specify some characteristic about the resource that the browser checks to determine if the files are the same. In the Last-Modified header, this is always a date. In the ETag header, this can be any value that uniquely identifies a resource (file versions or content hashes are typical).

Last-Modified is a “weak” caching header in that the browser applies a heuristic to determine whether to fetch the item from cache or not. (The heuristics are different among different browsers.) However, these headers allow the browser to efficiently update its cached resources by issuing conditional GET requests when the user explicitly reloads the page. Conditional GETs don’t return the full response unless the resource has changed at the server, and thus have lower latency than full GETs.

Read more!