1 // express_demo.js 文件 2 const fs = require('fs') 3 4 // 引入 express 并且创建一个 express 实例赋值给 app 5 const express = require('express') 6 const bodyParser = require('body-parser') 7 8 // 如果引入的模块省略了后缀名, 会找相应的 js 文件或者 json 文件 9 const { log } = require('./utils') 10 11 // const log = require('./utils').log 12 // 上面这行代码相当于下面两行代码 13 // const a = require('./utils') 14 // const log = a.log 15 // { 16 // 'log': log, 17 // } 18 19 // new 一个 express 实例 20 const app = express() 21 22 const todoList = [] 23 24 // 配置静态文件目录 25 app.use(express.static('asset')) 26 // 注意 27 // 1. app.use 第一个必须是 static 28 // 2. bodyParser.json() 表示会自动解析 json 格式的数据 29 app.use(bodyParser.json()) 30 31 const sendHtml = (response, path) => { 32 let options = { 33 encoding: 'utf-8', 34 } 35 fs.readFile(path, options, (error, data) => { 36 // log(`读取的 html 文件 ${path} 内容是\n`, data) 37 // 表示把响应发送到客户端 38 response.send(data) 39 }) 40 } 41 42 const sendJSON = (response, data) => { 43 let r = JSON.stringify(data) 44 response.send(r) 45 } 46 47 // 用 get 定义一个给用户访问的网址 48 // request 是浏览器发送的请求 49 // response 是我们要发给浏览器的响应 50 // get 表示请求方法是 GET 51 // / 表示请求 path 是 / 52 // app.get('/', () => {}) 表示以 GET 方法访问 / 这个 path 53 // 会调用 () => {} 这个回调函数 54 app.get('/', (request, response) => { 55 let path = 'index.html' 56 sendHtml(response, path) 57 }) 58 59 app.get('/todo/all', (requrest, response) => { 60 sendJSON(response, todoList) 61 }) 62 63 const todoAdd = (form) => { 64 // 给新增的 todo 增加 id 属性 65 // 在 todoList.push 之前 66 // 如果 todoList 里面有 todo 67 // todo.id 就是 todoList 里最后一个 todo 的 id + 1 68 // 如果 todoList 没有 todo 69 // todo.id 为 1 70 if (todoList.length === 0) { 71 form.id = 1 72 } else { 73 let tailTodo = todoList[todoList.length - 1] 74 form.id = tailTodo.id + 1 75 } 76 todoList.push(form) 77 return form 78 } 79 80 app.post('/todo/add', (request, response) => { 81 let form = request.body 82 let todo = todoAdd(form) 83 sendJSON(response, todo) 84 }) 85 86 const todoDelete = (id) => { 87 id = Number(id) 88 let index = -1 89 for (let i = 0; i < todoList.length; i++) { 90 let t = todoList[i] 91 if (t.id === id) { 92 index = i 93 break 94 } 95 } 96 97 // 通过判断 index 的值来查看是否找到了这个 todo 98 if (index > -1) { 99 let t = todoList.splice(index, 1)[0] 100 return t 101 } else { 102 return {} 103 } 104 } 105 106 107 // delete 这个路由函数用了一个叫做 动态路由 的概念 108 // 其中 :id 是一个动态变量 109 // 它可以匹配如下 url 110 // /todo/delete/1 111 // /todo/delete/2 112 113 // 甚至可以匹配下面的 url 114 // /todo/delete/error 115 app.get('/todo/delete/:id', (request, response) => { 116 // 动态路由的变量通过 request.params.id 的方式获取 117 // 变量类型永远是 string 118 let id = request.params.id 119 let todo = todoDelete(id) 120 sendJSON(response, todo) 121 }) 122 123 const main = () => { 124 // listen 函数的第一个参数是我们要监听的端口 125 // 这个端口是要浏览器输入的 126 // 默认的端口是 80 127 // 所以如果你监听 80 端口的话,浏览器就不需要输入端口了 128 // 但是 1024 以下的端口是系统保留端口,需要管理员权限才能使用 129 let server = app.listen(5000, () => { 130 let host = server.address().address 131 let port = server.address().port 132 133 log(`应用实例,访问地址为 http://${host}:${port}`) 134 }) 135 } 136 137 // 这个是套路写法 138 if (require.main === module) { 139 main() 140 }