Web项目开发的过程中,一般会经过设计,切图静态化,程序。
设计工作是很独立的,与其他两个过程没什么关系。
但静态化和程序有时候就需要协作了,在我的实际工作中就遇到这样一个问题:前端在HTML页面里引用的资源路径都是相对的,在本地打开是没问题的,但交给程序后,在web服务器上访问时,往往需要修改这些路径,包括图片引用、样式引用、javascript引用、其他页面的连接等等,就算能批量替换也是很枯燥,而且如果前端又做了修改,这个替换还得做一遍。
所以,如果前端静态化的时候直接用像web服务器上的相对路径就可以解决这个问题了。
开始想的是让前端架设IIS,这样虽然可行,但是不同的项目还要指定不同的目录,前端操作比较复杂,于是就自己写了一个简单的静态文件服务器,只需将一个exe文件和一个配置文件复制到要浏览的目录就行了。
源码:
二进制:
特点:
- 基于.net3.5
- 可自定义端口
- 可扩展Mime类型
- 可浏览目录
代码其实是很简单,就是用httpListenner处理GET请求,有注释,不再说明:
class Program { //根目录 static string RootPath = System.Environment.CurrentDirectory; //端口 static string Port = GetSetting("port") ?? "80"; //Mime类型映射 static DictionaryMimeMaps = new Dictionary (); [STAThread] static void Main(string[] args) { try { //加载MimeMap; LoadMimeMaps(); var url = "http://localhost:" + Port + "/"; var httpListenner = new HttpListener(); httpListenner.AuthenticationSchemes = AuthenticationSchemes.Anonymous; httpListenner.Prefixes.Add(url); httpListenner.Start(); Console.WriteLine("服务已启动:{0}", url); //打开浏览器 System.Diagnostics.Process.Start(url); new Thread(new ThreadStart(delegate { try { LoopHandle(httpListenner); } catch (Exception exp) { Console.WriteLine(exp); } })).Start(); } catch (Exception exp) { Console.WriteLine(exp); } } /// /// 循环处理请求 /// /// private static void LoopHandle(HttpListener httpListenner) { while (true) { HttpListenerContext context = httpListenner.GetContext(); HttpListenerRequest request = context.Request; HttpListenerResponse response = context.Response; var file = request.Url.LocalPath.Replace('/', '\\'); var path = RootPath + file; response.ContentEncoding = Encoding.UTF8; if (File.Exists(path)) { HandleFile(response, path); } else if (Directory.Exists(path)) { HandleDirectory(request, response, path); } else { HandleNotFound(response, path); } response.Close(); } } ////// 处理文件请求 /// /// /// private static void HandleFile(HttpListenerResponse response, string path) { response.ContentType = GetContentType(path); var buffer = File.ReadAllBytes(path); response.OutputStream.Write(buffer, 0, buffer.Length); } ////// 处理文件夹请求 /// /// /// /// private static void HandleDirectory(HttpListenerRequest request, HttpListenerResponse response, string path) { StringBuilder sb = new StringBuilder(); sb.Append(""); sb.Append(""); sb.Append(" "); sb.Append("dir "); sb.Append(""); sb.Append(""); sb.Append(""); var dirList = Directory.GetDirectories(path); foreach (var dir in dirList) { var vdir = Path.GetFileName(dir); sb.AppendFormat("
"); sb.Append(""); sb.Append(""); response.ContentType = "text/html"; var buffer = Encoding.UTF8.GetBytes(sb.ToString()); response.OutputStream.Write(buffer, 0, buffer.Length); } ///- {1}
", Path.Combine(request.Url.LocalPath, vdir), vdir); } var fileList = Directory.GetFiles(path); foreach (var f in fileList) { var vf = Path.GetFileName(f); if (!vf.StartsWith("StaticFilesServer.exe")) { sb.AppendFormat("- {1}
", Path.Combine(request.Url.LocalPath, vf), vf); } } sb.Append("/// 处理404 /// /// /// private static void HandleNotFound(HttpListenerResponse response, string path) { StringBuilder sb = new StringBuilder(); sb.Append(""); sb.Append(""); sb.Append(" "); sb.Append("404 "); sb.Append(""); sb.Append(""); sb.AppendFormat("没有找到文件:{0}
", path); sb.Append(""); sb.Append(""); response.ContentType = "text/html"; var buffer = Encoding.UTF8.GetBytes(sb.ToString()); response.OutputStream.Write(buffer, 0, buffer.Length); } ////// 得到请求内容的ContentType /// /// ///private static string GetContentType(string path) { var ext = Path.GetExtension(path).ToLower(); string mime; if (MimeMaps.TryGetValue(ext, out mime)) { return mime; } else { return ""; } } /// /// 加载MimeMaps /// private static void LoadMimeMaps() { var value = GetSetting("mimeMaps"); var lines = value.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) { var one = line.Replace(" ", "").Replace(" ", "").ToLower(); if (one.Length > 0) { var part = one.Split(new string[] { "=>" }, StringSplitOptions.RemoveEmptyEntries); MimeMaps[part[0]] = part[1]; } } } private static string GetSetting(string key) { var value = System.Configuration.ConfigurationManager.AppSettings.Get(key); return value; } }
测试文件夹结构:web\web\index.htmlweb\StaticFilesServer.exeweb\StaticFilesServer.exe.configweb\content\web\content\image.pngweb\content\style.css双击StaticFilesServer.exe会启动服务,并会在默认浏览器中打开web根目录: