node.jsリンク短縮サービス



こんにちは、Habr! この記事では、mysql-libmysqlclient、サーバー上のMooTools、およびクライアント上のjQueryを使用して、node.jsリンク短縮サービスである単純なWebアプリケーションを作成するプロセスを説明します。 この記事では、読者が「Hello world」の演習を既に完了し、node.jsの基本を理解していることを前提としています。



私はすぐにあなたに警告しなければなりません-私はnode.jsの専門家とは考えていません。 コードについて話し合い、一緒に理想に近づくことを提案します。 おそらく一緒に私たちは初心者のための素晴らしい例を作るでしょう。 したがって、建設的な批判を歓迎します。



サーバーMooTools



私は、必要としないというテーマに言及したくありません。使用することを好みます。それ以外の場合は決定できます。

MooToolsをすぐに接続できませんでした-ただそれを取得して、サーバーファイルをダウンロードして必要とすることはできません( './ MooTools')。

7月12日のMooToolsのツイートdavidwalsh.name/mootools-nodejsのリンクに助けられました。 その結果、ライブラリは次のように接続されました。

require('./Lib/MooTools').apply(GLOBAL);
      
      







MySQL



一部のNoSQLデータベースはこのアプリケーションにより適していますが、私の目標はnode.jsでMySQLを操作する方法を学ぶことでした。

ブックマークからNode-mysql-libmysqlclientに関するトピックを取り上げ、必要な情報をすべて入手し、マニュアルを使用して問題なくクライアントを組み立てました。

スクリプトは次のように簡単に開始できるため、プロジェクト内のLib



フォルダーにスクリプト自体を投げました。

 var conn = require('./Lib/mysql/mysql-libmysqlclient').createConnectionSync(); conn.connectSync('localhost', 'NAME', 'PASS', 'nodejs');
      
      







ServerResponseを拡張する



アプリケーションでヘッダーを指定してリダイレクトするのが便利になるように、MooTools implementsメソッドを使用してServerResponseプロトタイプ(このアプローチはJavaScriptイデオロギーに対応すると考えています)を拡張することにしました。

 var http = require('http'); http.ServerResponse.implement({ // code -    .   ,  200 (Ok)  404 (Not Found) // plain -     true,  - html header : function (code, plain) { this.writeHead(code, { 'Content-Type': plain ? 'text/plain' : 'text/html' }); }, // response.redirect('http://example.com')      redirect : function (url, status) { this.writeHead(status || 302, { 'Content-Type' : 'text/plain', 'Location' : url }); this.write('Redirecting to ' + url); this.end(); } });
      
      







アプリケーションワイヤーフレーム



 http.createServer(function (req, res) { // code will be here }).listen(8124, "127.0.0.1"); console.log('Server running at http://127.0.0.1:8124/');
      
      







リンク、 Link.js



ファイル



したがって、リンクには3つのプロパティがあります。データベースのID、リンク先のURL、短縮サービスに表示されるコードです。

データベースに個別にコードを書くのではなく、idに基づいてコードを受け取り、36ビットの数値システム([0-9a-z])に変換します。

 Link.getCode = function (id) { return id ? id.toString(36) : null; }; Link.fromCode = function (code) { return code ? parseInt(code, 36) : null; };
      
      







これに基づいて、静的メソッドの前に配置するリンククラス自体を構築します。

 Link = new Class({ initialize : function (obj) { //      -      this.setId(obj.id).id || this.setCode(obj.code); this.setUrl(obj.url); }, setId : function (id) { // id    int this.id = (isNaN(id) || id <= 0) ? null : parseInt(id); return this; }, getId : function () { return this.id; }, setUrl : function (url) { this.url = url || null; return this; }, getUrl : function () { return this.url; }, setCode : function (code) { this.id = Link.fromCode(code); return this; }, getCode : function () { return Link.getCode(this.id); } });
      
      







データベースで、単純なテーブルを作成し、リンクを取得して挿入するモデルを作成します。

 CREATE TABLE `shortLinks` ( `id` int(11) NOT NULL AUTO_INCREMENT, `url` varchar(512) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
      
      







 Model = new Class({ initialize : function (conn) { //       this.conn = conn; }, create : function (args) { //     ,     return new Link(args); }, get : function (link, fn) { //     if (!link.getId()) throw 'EmptyId'; //  .  ,  link.id    int var q = 'SELECT * FROM `shortLinks` WHERE `id` = ' + link.getId(); //    .   . this.conn.query(q, function (err, res) { if (err) throw err; res.fetchAll(function (err, rows) { if (err) throw err; //     -,    fn(rows.length ? link.setUrl(rows[0].url) : null); res.freeSync(); }); }); }, put : function (link, fn) { // url - ,  !!    var q = 'INSERT INTO `shortLinks` (`id`, `url`) ' + 'VALUES (NULL , "' + this.conn.escapeSync(link.getUrl()) + '");' this.conn.query(q, function (err, res) { if (err) throw err; //       fn(link.setId( //       this.conn.lastInsertIdSync() )); }.bind(this)); } }); //     exports.Link = Link; exports.Model = Model;
      
      







初期化に次の行を追加できます。

 var linkModel = new (require('./Link').Model)(conn);
      
      





require('./Link').Model



周りの括弧require('./Link').Model



注意してくださいrequire('./Link').Model



そうでない場合はrequire



オブジェクトを作成しようとします。



レンダラー、 Renderer.js



ファイル





 //        require('./Lib/MooTools').apply(GLOBAL); //     var url = require('url'); //      var fs = require('fs'); exports.Renderer = new Class({ initialize : function (linkModel) { this.link = linkModel; } });
      
      







Link.Modelなどのレンダラーは、アプリケーションの初期化中に1回だけ作成され、各リクエストは同じように使用されます。そのため、貴重なミリ秒が失われることはありません。

基本はrunメソッドになります。



 run : function (req, res) { var path = url.parse(req.url, true); if (path.query && 'add' in path.query) { var addUrl = path.query.add; //      , , "example.com" //        ,   default- if (!url.parse(addUrl).protocol) { addUrl = 'http://' + addUrl; } //    this.add(res, addUrl); //     ( url/!abc12 ) } else if (path.pathname.test(/^\/![0-9a-z]+$/)) { //      (/!)    this.send(res, path.pathname.substr(2)); } else { //        this.index(res); } },
      
      







まだ忘れていません-少し編集します./init.js





 var linkModel = new (require('./Link').Model)(conn); var renderer = new (require('./Renderer').Renderer)(linkModel); http.createServer(function (req, res) { renderer.run(req, res); }).listen(8124, "127.0.0.1");
      
      







なぜなら リンクはajaxによって追加されます。必要なのは、データベースへのリンクを作成し、そのコードを返すことだけです。

 add : function (res, url) { res.header(200); this.link.put( this.link.create({ url : url }), function (link) { res.end(link.getCode()); } ); },
      
      







ユーザーが短縮リンクをクリックする場合-必要に応じてヘルメットを送信するか、そのようなリンクがないことを通知します

 send : function (res, code) { this.link.get( this.link.create({ code : code }), function (link) { if (link) { res.redirect(link.getUrl()); } else { res.header(404, true); res.end('There is not such url'); } } ); },
      
      







メインページの場合-index.htmlファイルを印刷するだけです。 最初に__dirnameを使用してパスを指定することをお勧めします。 そうしないと、問題が発生する可能性があります

 index : function (res) { fs.readFile(__dirname + '/index.html', function (err, data) { if (err) throw err; res.header(200); res.end(data); }) }
      
      







メインページ



メインページで、それを行います-レイプからGoogle gikveryを接続し、入力フィールドを追加し、ユーザーがリンクを短くしたい場合-ajaxを使用して新しいリンクのコードを受け取り、入力フィールドの下に美しく表示します。

 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>   node.js</title> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> <script>
      
      





 $(function () { $('input[type=submit]').click(function() { var input = $('input[type=text]'); var url = input.val(); input.val(''); url && $.ajax({ url : './', data: ({ add : url }), success : function (data) { var result = location.protocol + '//' + location.host + '/!' + data; $('#url') .prepend( $('<dd>').append( $('<a>') .text(result) .attr('href', result) ) .hide() .fadeIn() ) .prepend( $('<dt>') .text(url) .hide() .fadeIn() ); } }); }) });
      
      





  </script> </head> <body> <div id="form"> <input type="text" /> <input type="submit" /> </div> <dl id="url"></dl> </body> </html>
      
      







それだけです

結果



すぐに警告する必要があります-リンクの安全性を保証することはできません。サービスは非常に実証的です。



pastebinの1か所にすべてのコード



All Articles