📜 ⬆️ ⬇️

Simple parse URL using isomorphic Javascript

Many web applications require parsing of URLs, such as retrieving a domain name, implanting a REST API, or finding the path to image files. A typical URL structure is shown below:



You can parse the URL string into components using regular expressions, but this is an unjustified and complicated decision ...

Server Parsing


Node.js (like its fork io.js) provides the URL API :
// Server-side JavaScript var urlapi = require('url'), url = urlapi.parse('http://site.com:81/path/page?a=1&b=2#hash'); console.log( url.href + '\n' + // the full URL url.protocol + '\n' + // http: url.hostname + '\n' + // site.com url.port + '\n' + // 81 url.pathname + '\n' + // /path/page url.search + '\n' + // ?a=1&b=2 url.hash // #hash ); 

As you can see in the example above, the parse () method returns an object containing all the individual parts of the URL, such as protocol, port, host address, and so on.
')

Analysis on the client


In the browser, unfortunately, there is no similar method, but the browser is able to well manipulate DOM elements that implement a simple Location interface:
 //  JavaScript //     DOM var url = document.getElementsByTagName('a')[0]; console.log( url.href + '\n' + // the full URL url.protocol + '\n' + // http: url.hostname + '\n' + // site.com url.port + '\n' + // 81 url.pathname + '\n' + // /path/page url.search + '\n' + // ?a=1&b=2 url.hash // #hash ); 

If we have a URL string, we can parse it in memory using the anchor element (a) without using regular expressions:
 //  JavaScript //    var url = document.createElement('a'); url.href = 'http://site.com:81/path/page?a=1&b=2#hash'; console.log(url.hostname); // site.com 


Isomorphic parse URL


Aurelio De Rosa discussed recently isomorphic JavaScript applications . In short, this is a progressive improvement that sets a new level, when applications can run equally well on both the client and the server. A user with a modern browser will use a single-page (single-page) application. Older browsers and search robots will use alternative mechanisms that process requests on the server. In theory, applications can implement different levels of client-server processing, depending on the width of the channel and the capabilities of the client.
Isomorphic Javascript has been discussed for many years and this issue is complex. Some projects have gone further than just creating shared views, because in reality there are not many situations where progressive improvement will not work as well (if not better, because most of the “isomorphic” Javascript frameworks do not exist without client processing). however, it is possible to create platform-independent microblocks that can help take the first step towards an isomorphic concept.
Let's discuss how we can create such a library to parse URLs in the lib.js file. First you need to determine where our code is running:
 //  Node.js? var isNode = (typeof module === 'object' && module.exports); 

This is not the best way to define a platform, since you can have a client object defined with the module.exports method, but I don't know the method better. Other developers check the window object:
 //  Node.js? var isNode = typeof window === 'undefined'; 

Let's finish our code in the file lib.js
 // running on Node.js? var isNode = (typeof module === 'object' && module.exports); (function(lib) { "use strict"; // require Node URL API var url = (isNode ? require('url') : null); // parse URL lib.URLparse = function(str) { if (isNode) { return url.parse(str); } else { url = document.createElement('a'); url.href = str; return url; } } })(isNode ? module.exports : this.lib = {}); 

In this example, for clarity, I used the isNode variable. In any case, you can replace this check by placing it directly in the last brackets of this code.
On the server, URLParse is exported as a standard Common.JS module. Example:
 // include lib.js module var lib = require('./lib.js'); var url = lib.URLparse('http://site.com:81/path/page?a=1&b=2#hash'); console.log( url.href + '\n' + // the full URL url.protocol + '\n' + // http: url.hostname + '\n' + // site.com url.port + '\n' + // 81 url.pathname + '\n' + // /path/page url.search + '\n' + // ?a=1&b=2 url.hash // #hash ); 

On the client, URLParse is declared as a method of the global lib object:
 <script src="./lib.js"></script> <script> var url = lib.URLparse('http://site.com:81/path/page?a=1&b=2#hash'); console.log( url.href + '\n' + // the full URL url.protocol + '\n' + // http: url.hostname + '\n' + // site.com url.port + '\n' + // 81 url.pathname + '\n' + // /path/page url.search + '\n' + // ?a=1&b=2 url.hash // #hash ); </script> 

This library has no differences in use on the server and the client, except for the method of connecting to the code.

Truth be told, this is simple code and the URLParse method runs (almost always) separately on the server and client. But we have created a permanent API that shows how to write Javascript code that can be run anywhere. We can extend the library to other client and server functions, such as data validation, cookie analysis, date handling, currency formatting, etc.
But I’m not sure if applications are completely isomorphic, because different logic is often required for processing on the client and the server. In any case, platform-independent libraries can reduce your costs of creating different code that does the same things.

Source: https://habr.com/ru/post/252533/


All Articles