用NodeJs短网址还原的思路:
1.用已有的服务器api 这里
var sys = require("sys"), http = require("http"), url = require("url"), events = require("events"), emitter = new events.EventEmitter(); // unshorten url function _unshorten(){ var _body = '', _host = "api.unshort.me", _client = http.createClient(80, _host), _request = _client.request("GET", api, {"host": _host}); _request.on("response", function(_response){ _response.on("data", function(_data){ _body += _data; }); _response.on("end", function(){ console.log(_body); var _data = JSON.parse(_body); emitter.emit("urldata", _data); }); }); _request.end(); }; // 创建http服务器实例 http.createServer(function(_request, _response){ var _url = url.parse(_request.url), _uri = _url.pathname; if (_uri === "/") { var _search = _url.search || '?r='; api = _search + '&t=json'; emitter.once("urldata", function(_data){ _response.writeHead(200, {"Content-Type":"text/html"}); _response.write(''+ '<h2>' + (_data['success'] == 'true' ? ('解析后的URL — ' + _data['resolvedURL']) : ('URL无法解析 - ' + (_data['requestedURL']||'(空)'))) + '</h2>'); _response.end(); }); _unshorten(); } }).listen(8080); process.on('uncaughtException', function(_error){ console.log('Caught exception: ' + _error); }); // 打印启动信息 sys.puts("Server running at http://localhost:8080/");
2.递归请求短网址,知道没有出现redirect,即没有302或者301的状态码(这里)
var net = require('net'), http = require('http'), url = require('url'), fs = require('fs'); /* visit : http://127.0.0.1:1235/api?u=http://is.gd/imWyT */ var DEFAULT_PORTS = { 'http:': 80, 'https:': 443 }; //var INDEX_TPL = fs.readFileSync('index.html'); var INDEX_TPL = "<html><body>hello world</body><html>"; function _write(str, res, content_type) { if(res.jsonp_cb) { str = res.jsonp_cb + '("' + str + '")'; } res.writeHead(200, { 'Content-Length': str.length, 'Content-Type': content_type || 'text/plain' }); res.end(str); }; function expand(short_url, res) { var info = url.parse(short_url); // console.log('info: ' + JSON.stringify(info)); if(info.protocol != 'http:') { // 无法请求https的url? _write(short_url, res); return; } var client = http.createClient(info.port || DEFAULT_PORTS[info.protocol], info.hostname); var path = info.pathname || '/'; if(info.search) { path += info.search; } var headers = { host: info.hostname, 'User-Agent': 'NodejsSpider/1.0' }; var request = client.request('GET', path, headers); request.end(); request.on('response', function (response) { if(response.statusCode == 302 || response.statusCode == 301) { expand(response.headers.location, res); } else { _write(short_url, res); } }); }; //expand('http://sinaurl.cn/hbMUII'); // http服务 http.createServer(function(req, res){ if(req.url.indexOf('/api?') == 0) { var params = url.parse(req.url, true); if(params.query && params.query.u) { if(params.query.cb) { // 支持jsonp跨域请求 res.jsonp_cb = params.query.cb; } expand(params.query.u, res); } else { _write('', res); } } else { _write(INDEX_TPL, res, 'text/html'); } }).listen(1235); process.on('uncaughtException', function (err) { console.log('Caught exception: ' + err); });
3.服务器端获取socket.io的连接类型 (这里)
var io = require('socket.io'), io.Listener.prototype._onConnectionOld = io.Listener.prototype._onConnection; io.Listener.prototype._onConnection = function(transport, req, res, up, head){ req.socketIOTransport = transport; // Take note of the transport type this._onConnectionOld.call(this, transport, req, res, up, head); }; var socket = io.listen(app), socket.on('connection', function(client){ console.log(client.request.socketIOTransport); // Lets check that transport // ... });
4.NodeJs中数据库连接模式
//mydb.js module: var db exports.db = function() { if (db === null) { db = dblibrary.createClient() } return db } //Other modules: var db = require('mydb').db() ... db.query(...)
5.【不能用】nodejs 发送邮件,有一个mailer lib。参考 http://stackoverflow.com/questions/4113701/sending-emails-in-node-js
用本机的SMTP服务发送邮件 http://blog.nodejitsu.com/sending-emails-in-node
var mail = require("mailer"); // API 似乎已经更改,官方的是这样的 var email = require("../lib/node_mailer");
mail.send({ host : "localhost", // smtp server hostname port : "25", // smtp server port domain : "localhost", // domain used by client to identify itself to server to : "[email protected]", from : "[email protected]", subject : "node_mailer test email", body: "Hello! This is a test of the node_mailer.", authentication : "", // auth login is supported; anything else is no auth username : "yourname", // Base64 encoded username password : "yourepwd" // Base64 encoded password }, function(err, result){ if(err){ console.log(err); } });
6.hot-reloading http://stackoverflow.com/questions/1972242/auto-reload-of-files-in-node-js
isaacs出品,非常强悍 - http://github.com/isaacs/node-supervisor
npm install supervisor supervisor -p app.js
7.express 中的get post 参数传递 (带文件上传)
/*handle form in express
npm install connect-form
*/
var express = require("express"); var app = express.createServer(); app.use(express.cookieParser()); //server start app.get("/",function(req,res){ //res.send(req.cookies); //http://127.0.0.1:8000/?name=tom res.send(req.query);//{"name":"tom"} }); app.get("/user/:id",function(req,res){ //res.send(req.cookies); //http://127.0.0.1:8000/user/22 //res.send(req.params["id"]);//22 res.send(req.param("id"));//22 //note:相当于res.end() }); app.listen(8000); //end server
用connect-form 处理表单。需要注意的是connect-form不是express自带的,需要npm install connect-form
eg:
var express = require("express"); var form = require('connect-form'); var app = express.createServer( // connect-form (http://github.com/visionmedia/connect-form) // middleware uses the formidable middleware to parse urlencoded // and multipart form data form({ keepExtensions: true }) ); //!important to get req.body.name app.use(express.bodyParser()); app.get('/', function(req, res){ res.send('<form method="post" enctype="multipart/form-data">' + '<p>Image: <input type="file" name="image" /></p>' + 'Name: <input type="text" name="name" value="" />' + '<p><input type="submit" value="submit" /></p>' + '</form>'); }); app.post('/', function(req, res, next){ // connect-form adds the req.form object // we can (optionally) define onComplete, passing // the exception (if any) fields parsed, and files parsed req.form.complete(function(err, fields, files){ if (err) { next(err); } else { console.log('\nuploaded %s to %s' , files.image.filename , files.image.path); //res.send(JSON.stringify(fields)); res.send(fields.name); } }); // We can add listeners for several form // events such as "progress" req.form.on('progress', function(bytesReceived, bytesExpected){ var percent = (bytesReceived / bytesExpected * 100) | 0; process.stdout.write('Uploading: %' + percent + '\r'); }); }); app.listen(3000); console.log('Express app started on port 3000');
8. express 能自动生成项目
express 用expresso 进行模块测试
if (!module.parent) { app.listen(4000); }
9.express 提供静态服务
var express = require("express"); var app = express.createServer(); app.use(express.cookieParser()); app.configure(function(){ app.use(express.static(__dirname)); }); app.listen(8000); // see http://127.0.0.1:8000/main.js
10.图片的base64编码
var fs = require("fs"); var content = fs.readFileSync("a.jpg");//有一张同目录的jpg文件 //console.log(content); //var buf = new Buffer(content); content = content.toString("base64"); //do sth with content eg. post with url and compress it ... var img = new Buffer(content,"base64") fs.writeFileSync("a_"+(+new Date())+".jpg",img);
12.mongoose的好教程
14.又一个nodejs代理http://blog.nodejitsu.com/http-proxy-intro
15.nodejs hot-reload
supervisor npm install supervisor -g ,然后 supervisor main.js
还有这里 http://stackoverflow.com/questions/6310722/refresh-node-js-script
16.nodejs发送http头,实现跨域
this._response.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': 'true' });
17.你知道pipe是啥玩意儿不?
var net = require('net'); var server = net.createServer(function (c) { c.write('hello\r\n'); c.pipe(c); }); server.listen(8124, 'localhost');
c.pipe(c);什么的干活?!c.pipe(c) means 'echo data sent to c'
举个例子c1.pipe(c2); is a short version for
c1.on('data', function(buf) { c2.write(data); }); c2.on('data', function(buf) { c1.write(data); });
18.下载文件
app.get("/d",function(req,res){ res.download("a.jpg"); });
19.express 上传文件(7中已有介绍)
var express = require("express");
var form = require('connect-form');
var app = express.createServer(
// connect-form (http://github.com/visionmedia/connect-form)
// middleware uses the formidable middleware to parse urlencoded
// and multipart form data
form({ keepExtensions: true })
);
//!important to get req.body.name
app.use(express.bodyParser());
app.get('/', function(req, res){
res.send('<form method="post" enctype="multipart/form-data">'
+ '<p>Image: <input type="file" name="image" /></p>'
+ '<p><input type="submit" value="submit" /></p>'
+ '</form>');
});
app.post('/', function(req, res, next){
// connect-form adds the req.form object
// we can (optionally) define onComplete, passing
// the exception (if any) fields parsed, and files parsed
req.form.complete(function(err, fields, files){
if (err) {
next(err);
} else {
console.log('\nuploaded %s to %s'
, files.image.filename
, files.image.path);
res.redirect('back');
}
});
// We can add listeners for several form
// events such as "progress"
req.form.on('progress', function(bytesReceived, bytesExpected){
var percent = (bytesReceived / bytesExpected * 100) | 0;
process.stdout.write('Uploading: %' + percent + '\r');
});
});
app.listen(3000);
console.log('Express app started on port 3000');