Mastering Node.js(Second Edition)
上QQ阅读APP看书,第一时间看更新

The URL module

Whenever a request is made to an HTTP server, the request object will contain URL property, identifying the targeted resource. This is accessible via request.url. Node's URL module is used to decompose a typical URL string into its constituent parts. Consider the following figure:

We see how the url.parse method decomposes strings, and the meaning of each segment should be clear. It might also be clear that the query field would be more useful if it was itself parsed into key/value pairs. This is accomplished by passing true as the second argument of to the parse method, which would change the query field value given above into a more useful key/value map:

query: { filter: 'sports', maxresults: '20' }

This is especially useful when parsing GET requests. There is one final argument for url.parse that relates to the difference between these two URLs:

  • http://www.example.org
  • //www.example.org

The second URL here is an example of a (relatively unknown) design feature of the HTTP protocol: the protocol-relative URL (technically, a network-path reference), as opposed to the more common absolute URL.

To learn more about how network-path references are used to smooth resource protocol resolution, visit: http://tools.ietf.org/html/rfc3986#section-4.2.

The issue under discussion is this: url.parse will treat a string beginning with slashes as indicating a path, not a host. For example, url.parse("//www.example.org") will set the following values in the host and path fields:

host: null,
path: '//www.example.org'

What we actually want is the reverse:

host: 'www.example.org',
path: null

To resolve this issue, pass true as the third argument to url.parse, which indicates to the method that slashes denote a host, not a path:

url.parse("//www.example.org", null, true);

It is also the case that a developer will want to create an URL, such as when making requests via http.request. The segments of said URL may be spread across various data structures and variables, and will need to be assembled. You accomplish this by passing an object like the one returned from url.parse to the method url.format.

The following code will create the URL string http://www.example.org:

url.format({
protocol: 'http:',
host: 'www.example.org'
});

Similarly, you may also use the url.resolve method to generate URL strings in the common scenario of requiring the concatenating of a base URL and a path:

url.resolve("http://example.org/a/b", "c/d"); //'http://example.org/a/c/d'
url.resolve("http://example.org/a/b", "/c/d");
//'http://example.org/c/d'
url.resolve("http://example.org", "http://google.com"); //'http://google.com/'