留言板

1、初始化环境

koa2 test6

2、新建src文件夹,把下方四个文件放到src中


image.png

3、修改路径


image.png

4、规范目录与层级
image.png

5、安装mongoose

cnpm i mongoose --save

6、前端跨域允许带cookie的设置(在ajax.js中配置):

axios.defaults.withCredentials = true

服务端支持跨域的设置:
1、安装koa2-cors插件:

cnpm i koa2-cors --save

2、在app.js中配置:
先在上面引入

const cors = require('koa2-cors')

然后调用:
// 服务端支持跨域

app.use(cors({
origin: 'http://localhost:8080', // 支持前端哪个域可以跨域
credentials: true // 允许跨域的时候带着 cookie
}))

【origin:"" 支持前端所有的域可以跨域,前提是不要求跨域带cookie。也就是说服务端不要求跨域带cookie,origin的值可以是""。但是我们这里允许跨域的时候带着 cookie,那么origin的值就必须是一个具体的前端的域】
7、实现注册功能
1)定义路由

const router = require('koa-router')()
const { register } = require("../controller/user")

router.prefix('/users')
// 注册
router.post("/register", async (ctx, next) => {
  const userInfo = ctx.request.body
  // 提交注册
  try {
    const newUser = await register(userInfo);
    ctx.body = {
      errno: 0,
      data: newUser
    }
  } catch (ex) {
    console.error("注册失败", ex)
    ctx.body = {
      errno: -1,
      message: "注册失败"
    }
  }
})

module.exports = router

2)controller/user.js文件

const User = require("../model/User")
// 注册
async function register(userInfo = {}) {
    // 插入数据库
    const newUser = await User.create(userInfo)
    return newUser
}
module.exports = {
    register
}

8、实现登录验证
定义路由

const { register ,login} = require("../controller/user")
// 登录
router.post('/login', async (ctx, next) => {
  console.log(121212)
  // 获取登录信息
  const { username, password } = ctx.request.body
  // 验证登录
  const res = await login(username, password)
  if (res) {
    // 登陆成功
    // 设置 session
    ctx.session.userInfo = {
      username
    }

    // 返回
    ctx.body = {
      errno: 0
    }
  } else {
    // 登录失败
    ctx.body = {
      errno: -1,
      message: '登录验证失败'
    }
  }
})

user.js

// 登录
async function login(username, password) {
    // 从数据库查询用户,是否存在
    const user = await User.findOne({ username, password })
    if (user != null) {
        // 登录成功
        return true
    }
    // 登录失败
    return false
}

module.exports = {
    register,
    login
}

设置session的前提,先安装插件

 cnpm i koa2-cors --save

在app.js引入和配置

const session = require('koa-generic-session')
// 配置 session
app.keys = ['dssUII^*(*123123']
app.use(session({
  cookie: {
    path: '/',
    httpOnly: true,
    maxAge: 24 * 60 * 60 * 1000 // 一天
  }
}))

登录验证的中间件

// 登录验证的中间件

async function loginCheck(ctx, next) {
    const session = ctx.session || {}
    const userInfo = session.userInfo
    if (userInfo && userInfo.username) {
        // 登录验证通过
        await next()
        return
    }
    // 登录验证失败
    ctx.body = {
        errno: -1,
        message: '用户尚未登录'
    }
}

module.exports = loginCheck

9、创建留言
1)新建文件(comment.js),定义路由

const router = require('koa-router')()
const loginCheck = require('../middleware/loginCheck')
const { create } = require('../controller/comment')

router.prefix('/comment')

// 创建留言
router.post('/create', loginCheck, async (ctx, next) => {
   // 获取留言信息
   const { content } = ctx.request.body
   const { username } = ctx.session.userInfo

   try {
       // 提交留言(controller)
       const newComment = await create(content, username)

       // 返回
       ctx.body = {
           errno: 0,
           data: newComment
       }
   } catch (ex) {
       console.error('创建留言失败', ex)
       ctx.body = {
           errno: -1,
           message: '创建留言失败'
       }
   }
})

module.exports = router

2)在app.js中引入和配置

const comment = require('./routes/comment')
app.use(comment.routes(), comment.allowedMethods())

3)存放到数据库中(controller/comment.js)


// 留言 controller

const Comment = require('../model/Comment')

// 创建留言
async function create(content, username) {
    // 保存到数据库
    const newComment = await Comment.create({
        content,
        username
    })
    return newComment
}

module.exports = {
    create
}

10、获取留言列表

// 获取留言列表
router.get('/list', loginCheck, async (ctx, next) => {
    // 获取 filterType:1 - 全部;2 - 自己
    let { filterType } = ctx.query
    filterType = parseInt(filterType) || 1

    // 获取当前用户名
    let username = ''
    if (filterType === 2) {
        username = ctx.session.userInfo.username
    }

    // 获取留言列表
    const list = await getList(username)
    ctx.body = {
        errno: 0,
        data: list
    }
})

controller/comment.js

// 获取留言列表
async function getList(username = '') {
    const whereOpt = {}
    if (username) {
        whereOpt.username = username
    }

    const list = await Comment.find(whereOpt).sort({ _id: -1 })
    return list
}

11、删除留言

// 删除留言
router.post('/del', loginCheck, async (ctx, next) => {
    // 获取 id
    const { _id } = ctx.request.body
    // 获取用户名
    const { username } = ctx.session.userInfo
    // 执行删除
    try {
        await del(_id, username)
        ctx.body = {
            errno: 0
        }
    } catch (ex) {
        // 失败
        console.error('删除失败', ex)
        ctx.body = {
            errno: -1,
            message: '删除失败'
        }
    }
})

controller/comment.js

// 删除留言
async function del(_id, username) {
    await Comment.remove({
        _id,
        username // 只能删除自己的留言
    })
}

11、更新留言

// 更新留言
router.post('/update', loginCheck, async (ctx, next) => {
    // 获取 id content
    const { _id, content } = ctx.request.body
    // 获取用户名
    const { username } = ctx.session.userInfo
    // 执行更新
    try {
        const newData = await update(_id, username, content)
        ctx.body = {
            errno: 0,
            data: newData
        }
    } catch (ex) {
        // 失败
        console.error('更新失败', ex)
        ctx.body = {
            errno: -1,
            message: '更新失败'
        }
    }
})

controller/comment.js

// 更新留言
async function update(_id, username, content) {
    const newData = await Comment.findOneAndUpdate(
        { _id, username }, // 只能跟新自己的留言
        { content },
        { new: true } // 返回更新之后的最新留言
    )
    return newData
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343