用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 : "cookieu@gmail.com",
from : "cookieu@gmail.com",
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');