目录
在本地、开发机上工作时,有时想下载或预览一些文件,需要临时开一个Web Server,参考当时服务器已安装的软件,可尝试下列几种方式:
python2
python -m SimpleHTTPServer 8080
python3
python -m http.server 8080
php
php -S 0.0.0.0:8080
# 完整参数
# php [options] -S <addr>:<port> [-t docroot] [router]
nginx
如果已经安装了nginx,但又不想影响正常服务,可以临时起一个新的server。
编辑一个新的conf文件,如my_server.conf
, 内容:
daemon off; # 前台运行,防止忘记停服务的安全风险。如不需要可删除这行。
events {
worker_connections 32;
}
http {
server {
listen 8080;
location / {
root /root/www; # 根目录
autoindex on; # 打开索引
}
}
}
编辑完成,运行:
nginx -c /path/to/my_server.conf # 注意完整路径
node npm
npm install -g http-server
http-server -p 8080
nodejs
上面介绍了npm安装包的方式,如果仍觉麻烦,可以直接编辑文件server.js
并运行:
function startServer() {
const args = process.argv.slice(2);
const cluster = require('cluster');
const numCPUs = require('os').cpus().length;
if(args[0] === '-h' || args[0] === '--help') {
console.log("node server.js [port] [host]");
return;
}
if (cluster.isMaster) {
console.log('[pid:%s] Master is running', process.pid);
for (let i = 0; i < numCPUs; i++) cluster.fork();
return;
}
const util = require('util');
const fs = require('fs');
const http = require('http');
const port = parseInt(args[0]) || 8080;
const url = require('url');
const stat = util.promisify(fs.stat);
const readdir = util.promisify(fs.readdir);
const access = util.promisify(fs.access);
const path = require('path');
const mimeType = {};
const texts = 'txt|html|htm|js|json|css|ini|py|sh|log|org|php|md'.split('|').forEach(v => mimeType[`.${v}`] = `text/${v}`);
const images = 'jpg|png|jpeg|gif'.split('|').forEach(v => mimeType[`.${v}`] = `image/${v}`);
var host = args[1] || 'localhost';
var server = http.createServer(async function (request, res) {
var u = url.parse(request.url);
var prefix = u.pathname;
var filepath = '.' + decodeURIComponent(u.pathname);
var s = await stat(filepath).catch(e=>{page(404, 'Not Found');});
if(!s) return;
if(s.isFile()) {
access(filepath, fs.constants.F_OK | fs.constants.R_OK)
.catch(e=>{ page(403, 'File Read Error'); })
.then(function() {
var ext = path.parse(filepath).ext;
res.setHeader('Content-type', mimeType[ext.toLowerCase()] || 'application/octet-stream');
fs.createReadStream(filepath, {"bufferSize": 4096})
.on('end', function() {
console.log(['HTTP', 200, filepath.slice(1)].join(' '));
})
.pipe(res);
});
}
else if(s.isDirectory()) {
var files = await readdir(filepath).catch(e=>{ page(403, 'Dir Read Error'); });
if(prefix !== "/") prefix += '/';
var html = files.map(f => `<a href="${prefix}${f}">${f}</a>`).join('<br>');
page(200, html, '.html');
}
else page(403, 'Forbidden');
function page(statusCode, html, mime) {
res.statusCode = statusCode;
res.setHeader('Content-type', 'text/html;charset=utf-8');
res.write(html || '');
res.end();
console.log(['HTTP', statusCode, filepath.slice(1)].join(' '));
}
}).listen(port, host);
server.on('error', function(e) {
if (e.code === 'EADDRINUSE') {
console.error(`port[${port}] in use, retrying...`);
setTimeout(() => {
server.close();
server.listen(port, host);
}, 1000);
}
else console.error(e);
})
console.log('[pid:%s] server start at %s:%s', process.pid, host, port);
}
startServer(); // 启动服务
编辑完成,运行:
node server.js # 默认8080端口
# 该示例使用了cluster,可以充分利用机器的多核性能
# 完整用法:
# node server.js [port] [host]