查看: 859|回复: 0

[DIV/CSS] nodejs 实现的简单server.js模块 方便本地vue开发调试

发表于 2017-7-22 08:00:02

因为最近在学习vue.js,需要渲染网页。但是搭建php的环境又感觉略复杂,所以用nodejs学习谢了一个server.js 用于方便自己本地的页面调试。要求的功能如下

支持html页面的访问

支持默认index.html、index.htm文件访问

支持路由+完整路径访问

关于第2条,访问 http://localhost.com:8080/vue/ 指向 vue/index.html文件

项目地址

https://github.com/sunshinev/sunhuajie_node_server

目录结构
  1. sunhuajie:node sun.huajie$ tree
  2. .
  3. ├── index.js // 启动服务的文件
  4. ├── lyric.txt // 读写测试的文本文件
  5. ├── node_modules
  6. │ └── huajie_server // 自定义模块
  7. │ ├── package.json // 模块配置
  8. │ ├── requesthandler.js // 请求处理脚本
  9. │ ├── router.js // 路由脚本
  10. │ └── server.js // 服务创建脚本
  11. └── vue // 工作目录
  12. └── index.html
复制代码
服务创建过程

index.js 启动

因为将server封装为了一个模块,所以每次启动的时候只需要引入,然后node index.js就可以了。

  1. #!/usr/bin/env node
  2. var server = require('huajie_server');
  3. server.create();
复制代码

效果如图:

  1. sunhuajie:node sun.huajie$ node index.js
  2. the port is 8080
复制代码

server.js 创建服务

_onRequest 实现了对请求的处理,并且作为闭包传递给 http.createServer 。状态码由路由层进行返回。

  1. #!/usr/bin/env node
  2. var http = require('http');
  3. var router = require('./router');
  4. // 创建server 默认端口为8080
  5. function create(port = 8080) {
  6. console.info('the port is '+port);
  7. http.createServer(_onRequest).listen(port);
  8. }
  9. // 处理请求
  10. function _onRequest(request, response) {
  11. // 路由
  12. var res = router.route(request.url);
  13. // 状态码
  14. response.writeHead(res.code,{});
  15. // 响应内容
  16. response.write(res.content);
  17. response.end();
  18. }
  19. exports.create = create;
复制代码

router.js 路由

路由此处跟php的mvc的 dispatcher (分发器)很像,分析url参数以及目录,实现文件指向。 这里有个小问题,就是当时写这个router的时候,其实应该将 requesthandler.js 里面的关于文件判断的部分放到router里面才算合理。但是当时为了方便就直接写到requesthandler里面了(后面给大家看这个文件)。

在路由这一层,实际上还可以添加一个 rewrite 的配置。先分析 url ,通过 rewrite 重新指向后,再把指向后的地址传递给 requesthandler 进行处理。

  1. #!/usr/bin/env node
  2. var url = require('url');
  3. var querystring = require('querystring');
  4. var requesthandler = require('./requesthandler');
  5. // todo 后期可以扩展路由部分
  6. function route(request_url) {
  7. // 解析地址
  8. var url_parse = url.parse(request_url);
  9. var url_path = url_parse['path'];
  10. var res = {};
  11. var code = 200;
  12. // 判断路径是否存在
  13. var content = requesthandler.handle(url_path);
  14. return {
  15. 'code':code,
  16. 'content':content
  17. }
  18. }
  19. exports.route = route;
复制代码

requesthandler.js 请求处理+文件指向

这个文件最简单的目的是实现对html文件的读取以及输出。但是我们加了一层默认文件,所以需要对目录进行遍历,并且判断当前的childnode是dir还是file。

默认可以访问 index.html 和 index.htm 两个文件。

_findFile 方法,首先判断当前传递的file_path是否是存在的文件,如果不是文件,那么在这个目录层级中进行搜索,是否存在默认可以访问的文件。进行遍历的时候,没有使用 forEach ,因为会遍历所有的文件,无论中间是否有 return 。

_isFile 方法,使用了try catch ,因为 fs.statSync 在文件不存在的时候,会抛出错误,导致脚本终止。

  1. #!/usr/bin/env node
  2. var fs = require('fs');
  3. // 默认检索文件,可以修改为配置项
  4. var default_files = [
  5. 'index.htm',
  6. 'index.html'
  7. ];
  8. function handle(url_path) {
  9. // 文件路径构造
  10. var file_path = '.' + url_path;
  11. // 判断路径是否存在
  12. var f_path = _findFile(file_path);
  13. if(!f_path) {
  14. return 'the path "'+file_path+'" is not exist';
  15. }else {
  16. var content = fs.readFileSync(f_path);
  17. return content;
  18. }
  19. }
  20. /**
  21. * 检索目录下的不同文件名是否存在,建立优先级
  22. * @return {[type]} [description]
  23. */
  24. function _findFile(file_path) {
  25. var is_file = _isFile(file_path);
  26. // 如果文件存在,直接返回路径
  27. if(is_file) {
  28. return file_path;
  29. }
  30. // 文件不存在,构造路径寻找文件
  31. var regex = /^\.\/[\w]*([\/][\w]+)?/;
  32. var regex_res = file_path.match(regex);
  33. // 匹配出目录路径 ./vue/test/s => ./vue/test
  34. if(!regex_res) {
  35. return '';
  36. }else {
  37. // 这里没有使用forEach,因为会遍历所有的值
  38. for(var i=0; i<default_files.length; i++) {
  39. var new_path = regex_res[0]+'/'+default_files[i];
  40. if(_isFile(new_path)) {
  41. return new_path;
  42. }
  43. }
  44. }
  45. }
  46. /**
  47. * 文件是否存在
  48. * @param {[type]} file_path [description]
  49. * @return {Boolean} [description]
  50. */
  51. function _isFile(file_path) {
  52. try {
  53. // 同步会抛出异常,所以用try来保证正常执行
  54. var stat = fs.statSync(file_path);
  55. // 返回是否是文件
  56. return stat.isFile();
  57. }catch(e) {
  58. console.info(e.message);
  59. }
  60. }
  61. exports.handle = handle;
复制代码
最终效果

启动

  1. sunhuajie:node sun.huajie$ node index.js
  2. the port is 8080
复制代码

浏览器访问

访问 实际
http://localhost:8080/vue/ 指向 index.html
http://localhost:8080/vue 指向 index.html
http://localhost:8080/ the path "./" is not exist
http://localhost:8080/vue/s the path "./vue/s" is not exist

来自:https://segmentfault.com/a/1190000008307856



回复

使用道具 举报