Node.js URL 模块的使用

Node.js 中的 URL 模块, 用于将 URL 字符串解析为对象或将对象格式化为 URL 字符串, 该模块比较简单, 共包括3个方法:

URL 各部分说明

对于一个 URL 字符串, 其组成部分会有所不同. 其中有些部分只有在 URL 字符串中存在时, 对应字段还才会出现在解析后的对象中. 以下是一个 URL 例子

http://user:pass@host.com:8080/path/to/file?query=string#hash
`</pre>

解析后的字段如下:
- `href`: 解析前的完整原始 URL, 协议名和主机名已经转为小写
- `protocol`: 请求协议, 小写, 例如`http:`
- `slashes`: 协议的`:`后面是否有`\`, 返回`true`或`false`
- `host`: URL 主机名, 包括端口信息, 小写, 例如`host.com:8080`
- `auth`: URL 中的认证信息, 例如`user:pass`
- `hostname`: 主机名, 小写, 例如`host.com`
- `port`: 主机的端口号, 例如`8080`
- `pathname`: URL 中的路径, 例如`/path/to/file`
- `search`: 查询对象, 即: `queryString`, 包括之前的`?`, 例如`?query=string`; 如果 `parseQueryString = true`, 则返回`{'query':'string'}`
- `query`: 例如`query=string`
- `hash`: 锚点部分, 即`#`之后的部分, 例如`#hash`

### 将 URL 字符串转换为对象: url.parse(urlStr[, parseQueryString[, slashesDenoteHost]])

`url.parse()`方法用于解析 URL 对象, 解析后范湖第一个 JSON 对象. 例如:

<pre>`&gt; var url = 'http://user:pass@host.com:8080/path/to/file?query=string#hash'
undefined
&gt; url
'http://user:pass@host.com:8080/path/to/file?query=string#hash'
&gt; var urlModule = require('url');
undefined
&gt; urlModule.parse(url)
Url {
  protocol: 'http:',
  slashes: true,
  auth: 'user:pass',
  host: 'host.com:8080',
  port: '8080',
  hostname: 'host.com',
  hash: '#hash',
  search: '?query=string',
  query: 'query=string',
  pathname: '/path/to/file',
  path: '/path/to/file?query=string',
  href: 'http://user:pass@host.com:8080/path/to/file?query=string#hash' }
`</pre>

第二个可选参数设置为`true`的时候, 会使用`queryString`模块来解析 URL 中的`query` 部分, 默认为`false`.

第三个参数为`true`的时候, 会把诸如`//foo/bar`这样的 URL 解析为 `{host: 'foo', pathname: '/bar'}`, 而不是 `{pathname: '//foo/bar'}`. 默认为`false`

### 将对象格式化为 URL 字符串: url.format(urlObj)

`url.resolve()`用于格式化URL对象, 输入一个 URL 对象, 返回格式化后的 URL 字符串, 例如:

<pre>`&gt; var url = require('url');
undefined
&gt; var urlObj = {
... protocol: 'http:',
... slashes: true,
... hostname: 'host.com',
... port: 8080,
... hash: '#hash',
... search: '?query=string',
... pathname: '/path/to/file'
... }
undefined
&gt; var result = url.format(urlObj)
undefined
&gt; result
'http://host.com:8080/path/to/file?query=string#hash'
`</pre>

### URL 路径处理

`url.resolve()`方法用于处理 URL 路径, 也可以用于处理锚点. 例如

<pre>`url.resolve('/one/two/three', 'four')         // '/one/two/four'
url.resolve('http://example.com/', '/one')    // 'http://example.com/one'
url.resolve('http://example.com/one', '/two') // 'http://example.com/two'

参数拼接, 如果之间没有/, 则参数二替换参数一末尾的文件名.

注意区分路径和文件名.

CommonJS 规范

概述
CommonJS 是服务器端模块的规范, Node.js 采用了这个规范

根据 CommonJS 规范, 一个单独的文件就是一个模块

加载模块使用 require 方法, 该方法读取一个文件并执行, 最后返回文件内部的 exports 对象.

// example.js

console.log('evaluating example.js');

var invisible = function(){
  console.log('invisible');
}

exports.message = 'h1';

exports.say = function(){
  console.log(message)
}
`</pre>

使用 require 方法, 加载 example.js 模块

<pre>`var example = require('./example.js');
`</pre>

这时变量 example 就对应模块中 exports 对象, 可以通过这个对象应用模块中提供的各种方法.

<pre>`{
  message: 'h1',
  say: [Function]
}
`</pre>

require 方法默认读取 js 文件, 所以可以省略 .js 扩展名

<pre>`var example = require('./example')
`</pre>

js 文件名前需要加上路径, 可以是相对路径, 也可以是绝对路径. 如果省略路径, node.js 会认为添加一个核心模块, 或者已经安装在本地 node_modules 目录中的模块. 如果加载的是一个目录, node.js 会首先寻找该目录中的 package.json 文件, 加载该文件 main 属性指定的模块, 否则就寻找该目录下的 index.js 文件

定义一个最简单的模块

<pre>`exports.add = function(a,b){return a+b};
`</pre>

//add.js
为 exports 对象添加一个 add 方法,

<pre>`var addition = require('./add');
addition.add(1,2); //3
`</pre>

稍复杂的例子

<pre>`//foobar.js
function foobar(){
  this.foo = function(){
    console.log('hello foo')
  };

  this.bar = function(){
    console.log('hello bar')
  };
}
exports.foobar = foobar;
`</pre>

调用

<pre>`var foobar = require('./foobar').foobar, test = new foobar();
test.bar(); //'hello bar'
`</pre>

有时不需要 exports 返回一个对象, 而仅需要返回一个函数, 就写成 module.exports

<pre>`module.exports = function(){
  console.log('hello world')
}
`</pre>

### AMD 规范与 CommonJS 规范的兼容性

CommonJS 规范加载模块是同步的, 也就是说, 只有加载完成, 才能执行后面的操作. AMD 规范则是非同步加载模块, 允许指定回调函数. 由于 Node.js 主要用于服务器编程, 模块文件一般都已经存在于本地硬盘, 所以加载起来比较快, 不需要考虑非同步加载的方式, 所以 CommonJS 的规范比较适用. 但是, 如果是浏览器环境, 要从服务器端加载模块, 这时就必须采用非同步模式, 因此浏览器端一般采用 AMD 规范.

AMD 规范适用 define 方法定义模块

<pre>`define(['package/lib', function(lib){
  function foo(){
    lib.log('hello world!');
  }

  return {
    foo:foo
  };
}])
`</pre>

AMD 规范允许输出的模块兼容 CommonJS 规范,在这时 define 方法需要写成如下格式

<pre>`define(function(require, exports, module)
  var someModule = require('someModule');
  var anotherModule = require('anotherModule');

  someModule.doTheAwesoem();
  anotherModule.doMoreAwesome();

  exports.asplode = function(){
    someModule.doTheAwesoem();
    anotherModule.doMoreAwesome();
  };
);
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×