NodeJS url验证(url-valid)的使用方法
NodeJS url验证(url-valid)的使用方法
发布时间:2016-12-30 来源:查字典编辑
摘要:Javascript做url检验,通常是使用正则表达式来判定,其格式是否正确,例如:复制代码代码如下:/^https?:///.test(u...

Javascript做url检验,通常是使用正则表达式来判定,其格式是否正确,例如:

复制代码 代码如下:

/^https?:///.test(url);

当然还有更好的检测方法比如基于RFC 3986, RFC 3966, RFC 4694, RFC 4759, RFC 4904等标准的进行验证的valid-url库。

不过个根据格式进行验证当然不能确定该url是否存在啦,所以就有了url-valid,我们基于HTTP请求进行验证。

接口设计

实际上我们只需要一个函数传入一个url地址,并回调返回该链接是否可用。

但请求容易产生未知错误,所以我们在回调函数传入一个error参数,如果不为空,则有错误产生。

我们可能还希望能够得到网页的相关数据,未来用在页面的信息提取上。

尽可能链式操作吧。

所以最后使用上大概是这样的:

复制代码 代码如下:

valid(url)

.on('check', function (err, status) {

if (err) throw err;

status ?

console.log('url是可用的') :

console.log('url是不可用的');

})

.on('data', function (err, data) {

console.log(data);

})

.on('end', function (err, data) {

console.log('请求结束');

})

HTTP GET 还是 HTTP HEAD

本来我们想利用HTTP HEAD请求来实现的,因为HEAD请求只会返回头信息,这可以减少请求时间,但是HEAD请求,不一定所有链接都会支持。

所以最后我们使用HTTP GET方式,在得到正确的statusCode后立刻abort掉请求。

处理301-303

因为301到303都是重定向状态所以,我们需要继续检查对应Location是否依然存在。

利用process.nextTick异步执行

为了在注册监听后,再执行代码,我们使用process.nextTick来一步操作。

实现

复制代码 代码如下:

/*!

* valid

* MIT Licensed

*/

module.exports = (function () {

'use strict';

var http = require('http')

, https = require('https')

, EventEmitter = require('events').EventEmitter

, URL = require('url')

, urlReg = /^(https?):///;

/**

* Valid

* @class

*/

function Valid(url, callback) {

var that = this;

this.url = url;

this.emitter = new EventEmitter();

process.nextTick(function () {

that.get(url);

});

this.fetch = false;

callback && this.emitter.on('check', callback);

}

Valid.prototype = {

constructor: Valid,

/**

* get

* @param {String} url

*/

get: function (url) {

var match = url.match(urlReg)

, that = this;

if (match) {

var httpLib = (match[1].toLowerCase() === 'http') ? http : https

, opts = URL.parse(url)

, req;

opts.agent = false;

opts.method = 'GET';

req = httpLib.request(opts, function (res) {

var statusCode = res.statusCode;

if (statusCode === 200) {

that.emitter.emit('check', null, true);

that.fetch ?

(res.on('data', function (data) {

that.emitter.emit('data', null, data);

}) && res.on('end', function () {

that.emitter.emit('end');

})) :

(req.abort() || that.emitter.emit('end'));

} else if (300 < statusCode && statusCode < 304) {

req.abort();

var emitter = that.emitter

, valid = one(URL.resolve(url, res.headers.location), function (err, valid) {

emitter.emit('check', err, valid);

});

that.fetch && valid.on('data', function (err, data) {

emitter.emit('data', err, data);

});

valid.on('error', function (err) {

that.emitter.emit('error', err);

});

valid.on('end', function () {

that.emitter.emit('end');

});

} else {

that.emitter.emit('check', null, false);

}

res.on('error', function (err) {

req.abort();

that.emitter.emit('data', err);

});

});

req.on('error', function (err) {

req.abort();

return that.emitter.emit('check', null, false);

});

req.end();

} else {

return that.emitter.emit('check', null, false);

}

},

/**

* on

* @param {Stirng} event

* @param {Function} callback

*/

on: function (event, callback) {

(event === 'data') && (this.fetch = true);

this.emitter.on(event, callback);

return this;

},

/**

* destroy

*/

destroy: function () {

this.emitter.removeAllListeners();

this.url = undefined;

this.emitter = null;

this.fetch = undefined;

},

/**

* removeAllListeners

* @param

*/

removeAllListeners: function (event) {

event ?

this.emitter.removeAllListeners(event) :

this.emitter.removeAllListeners();

return this;

},

/**

* listeners

* @param

*/

listeners: function (event) {

if (event) {

return this.emitter.listeners(event);

} else {

var res = []

, that = this

, _push = Array.prototype.push;

Object.keys(this.emitter._events).forEach(function (key) {

_push.apply(res, that.emitter.listeners(key));

});

return res;

}

}

}

/**

* one

* @param {String} url

* @param {Function} callback

* @return {Valid}

*/

function one(url, callback) {

return (new Valid(url, callback));

}

one.one = one;

return one;

})();

推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
相关阅读
网友关注
最新Javascript教程学习
热门Javascript教程学习
编程开发子分类