isadmin报错,且如果没有正常运行的问题

来源:7-18 联调演示与总结

Inuyasha__

2019-08-06

调了好久没调出来希望老师看看

首先是admin.html 因为直接在仓库复制,应该没有问题

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>管理中心</title>
    <style type="text/css">
        body {
            margin: 0 20px;
            line-height: 1;
        }
        a {
            text-decoration-line: none;
            cursor: pointer;
        }
        table {
            border: 1px solid #ccc;
        }
        table th {
            text-align: left;
            background-color: #f1f1f1;
        } 
        table td:nth-child(1) {
            width: 300px;
        }
    </style>
</head>
<body>
    <h1 style="border-bottom: 1px solid #ccc; padding-bottom: 10px;">管理中心</h1>
    <p>
        <a href="/new.html">新建博客</a>
    </p>
    <div style="margin-bottom: 10px;">
        <input id="text-keyword">
        <button id="btn-search">搜索</button>
    </div>
    <table id="table-container">
        <tr>
            <th>博客标题</th>
            <th colspan="2">操作</th>
        </tr>
    </table>

    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
    <script>
        // 发送 get 请求
        function get(url) {
            return $.get(url)
        }

        // 发送 post 请求
        function post(url, data = {}) {
            return $.ajax({
                type: 'post',
                url,
                data: JSON.stringify(data),
                contentType: "application/json",
            })
        }

        // 获取 url 参数
        function getUrlParams() {
            let paramStr = location.href.split('?')[1] || ''
            paramStr = paramStr.split('#')[0]
            const result = {}
            paramStr.split('&').forEach(itemStr => {
                const arr = itemStr.split('=')
                const key = arr[0]
                const val = arr[1]
                result[key] = val
            })
            return result
        }

        // 获取 dom 元素
        const $textKeyword = $('#text-keyword')
        const $btnSearch = $('#btn-search')
        const $tableContainer = $('#table-container')

        // 拼接接口 url
        let url = '/api/blog/list?isadmin=1'  // 增加一个 isadmin=1 参数,使用登录者的用户名,后端也需要修改 !!!
        const urlParams = getUrlParams()
        if (urlParams.keyword) {
            url += '&keyword=' + urlParams.keyword
        }

        // 加载数据
        get(url).then(res => {
            if (res.errno !== 0) {
                alert('数据错误')
                return
            }

            // 显示数据
            const data = res.data || []
            data.forEach(item => {
                $tableContainer.append($(`
                    <tr>
                        <td>
                            <a href="/detail.html?id=${item.id}" target="_blank">${item.title}</a>
                        </td>
                        <td>
                            <a href="/edit.html?id=${item.id}">编辑</a>
                        </td>
                        <td>
                            <a data-id="${item.id}" class="item-del">删除</a>
                        </td>
                    </tr>
                `))
            })
        })

        // 搜索
        $btnSearch.click(() => {
            const keyword = $textKeyword.val()
            location.href = '/admin.html?keyword=' + keyword
        })

        // 删除
        $tableContainer.click(e => {
            const $target = $(e.target)
            if ($target.hasClass('item-del') === false) {
                return
            }

            if (confirm('确定删除?')) {
                const url = '/api/blog/del?id=' + $target.attr('data-id')
                post(url).then(res => {
                    if (res.errno !== 0) {
                        alert('操作错误')
                        return
                    }
                    location.href = location.href
                })
            }
        })

    </script>
</body>
</html>

其次是blog.js

const { getList,
        getDetail,
        newBlog,
        updateBlog,
        delBlog } = require('../controller/blog')
const { SuccessModel, ErrorModel } = require('../model/resModel')

// 统一的登录验证函数
const loginCheck = (req) => {
    if (!req.session.username) {
        return Promise.resolve(new ErrorModel('尚未登陆'))
    }
}

const handleBlogRouter = (req, res) =>{
    const method = req.method
    const id = req.query.id

    if (method === 'GET' && req.path === '/api/blog/list'){
        let author = req.query.author || ''
        const keyword = req.query.keyword || ''
        // const listData = getList(author, keyword)
        
        //return new SuccessModel(listData)
        console.log('req' ,req.query)

        if(req.qeury.isadmin) {
            const loginCheckResult = loginCheck(req)
            if(loginCheckResult) {
                return loginCheckResult
            }
            author = req.session.username
        }
        
        

        const result = getList(author, keyword)
        return result.then(listData => {
            return new SuccessModel(listData)
        })
    }

    if (method === 'GET' && req.path === '/api/blog/detail'){
        // const data = getDetail(id)
        // return new SuccessModel(data)

        const result = getDetail(id)
        return result.then(data => {
            return new SuccessModel(data)
        })
    }

    if (method === 'POST' && req.path === '/api/blog/new'){
       
        const loginCheckResult = loginCheck(req)
        if (loginCheckResult) {
            return loginCheckResult
        }

        req.body.author = req.session.username
        const result = newBlog(req.body)
        return result.then( data => {
            return new SuccessModel(data)
        })
    }

    if (method === 'POST' && req.path === '/api/blog/update'){
        
        const loginCheckResult = loginCheck(req)
        if (loginCheckResult) {
            return loginCheckResult
        }
        const result = updateBlog(id, req.body)
        return result.then( val => {
            return val?new SuccessModel():new ErrorModel('更新博客失败')
        })
    }

    if (method === 'POST' && req.path === '/api/blog/del'){
       
        const loginCheckResult = loginCheck(req)
        if (loginCheckResult) {
            return loginCheckResult
        }

        const author = req.session.username     
        const result = delBlog(id,author)
        return result.then( val => {
            return val?new SuccessModel():new ErrorModel('删除博客失败')
        })
    }
}

module.exports = handleBlogRouter

和老师一点一点敲的,不知道为什么报错
(node:10020) UnhandledPromiseRejectionWarning: TypeError: Cannot read property ‘isadmin’ of undefined
at handleBlogRouter (G:\learningWeb\node.js\blog1\src\router\blog.js:27:26)
at get.then.then.postData (G:\learningWeb\node.js\blog1\app.js:102:28)
at process._tickCallback (internal/process/next_tick.js:68:7)
(node:10020) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)

我尝试打印 req.query 发现是NULL ?
可是我在 app.js中打印req.qeury 又是有isadmin的懵了

const querystring = require('querystring')
const handleBlogRouter = require('./src/router/blog')
const handleUserRouter = require('./src/router/user')
const { get, set } = require('./src/db/redis')

const getCookieExpires = () => {
    const d = new Date()
    d.setTime(d.getTime() + (24 * 60 * 60 * 1000))
    return d.toGMTString()
}

const getPostData = (req) => {
    const promise = new Promise((resolve, reject) => {
        if (req.method !== 'POST' || req.headers['content-type'] !== 'application/json'){
            resolve({})
            return
        }

        let postData = ''
        
        req.on('data', chunk => {
            postData += chunk.toString()
        })
        req.on('end', () => {
            if (!postData){
                resolve({})
                return
            }
            resolve(
                JSON.parse(postData)
            )
        })
    })
    return promise
}

const serverHandle = (req, res) => {
    // 设置返回格式 JSON
    res.setHeader('content-type',"application/json")
    
    // 获取 path
    const url = req.url
    req.path = url.split('?')[0]

    // 解析 query
    req.query = querystring.parse(url.split('?')[1])
    console.log(req.query)
    
    // 解析 cookie
    req.cookie = {}
    const cookieStr = req.headers.cookie || ''
    cookieStr.split(';').forEach( item => {
        if(!item) {
            return
        }
        const arr = item.split('=')
        const key = arr[0].trim()
        const val = arr[1].trim()
        req.cookie[key] = val
    })

    // 解析 session
    // let needSetCookie = false
    // let userId = req.cookie.userid
    // if (userId) {
    //     if (!SESSION_DATA[userId]) 
    //         SESSION_DATA[userId] = {}
    //     req.session = SESSION_DATA[userId]
    // } else {
    //     needSetCookie = true
    //     userId = `${Date.now()}_${Math.random()}`
    //     SESSION_DATA[userId] = {}
    // }
    // req.session = SESSION_DATA[userId]

    // 解析 session

    let needSetCookie = false

    let userId = req.cookie.userid
    if(!userId) {
        needSetCookie = true
        userId = `${Date.now()}_${Math.random()}`
        set(userId, {})
    }
    
    // 获取 session
    req.sessionId = userId
    get(req.sessionId).then(sessionData => {
        if(sessionData == null) {
            set(req.sessionId, {})
            req.session = {}
        } else {
            req.session = sessionData
        }
        console.log('req.session ', req.session)
        return getPostData(req)
    }).then( postData => {
        req.body = postData
       
        //处理 blog 路由
        const blogResult = handleBlogRouter(req, res)

        if (blogResult){
            blogResult.then( blogData => {
                if(needSetCookie) {
                    res.setHeader('Set-Cookie', `userid=${userId}; path=/; httpOnly; expires=${getCookieExpires()}`)
                }
                res.end(
                    JSON.stringify(blogData)
                )
            })
            return
        }
        


        const userResult = handleUserRouter(req, res)
        if (userResult){
            userResult.then(userData => {
                if(needSetCookie) {
                    res.setHeader('Set-Cookie', `userid=${userId}; path=/; httpOnly; expires=${getCookieExpires()}`)
                }
                res.end(
                    JSON.stringify(userData)
                )
            })
            return
        }

        res.writeHead(404, {"Content-type": "text/plain"})
        res.write("404 Not Found\n")
        res.end()
    })  
}

module.exports = serverHandle

最后发现还有几个地方和老师不一样
以下均在无痕页面访问
1.我登录localhost:8080/admin.html
并不会弹出那个数据错误之类的 但是进去编辑和删除无法做到 会显示操作错误
2.我登录localhost:8080/index.html 再加上isadmin之后就会报以上的错误
3.登录localhost:8080/login.html 错误登录没有报提示信息,正确登录会跳转到 admin.html
然而网址不会加上isadmin 就是可以操作其他人的博客

问题有点多···如果老师可以花时间看的话,感激万分。

写回答

1回答

双越

2019-08-06

不对吧,如果 req.query === null 的话,应该从 let author = req.query.author || '' 这一行就开始报错,走不到 req.query.isadmin 这样。

0
3
双越
回复
Inuyasha__
如果是一个比较怪异的 bug ,且不影响学习进度,就先别管它。先把课程整体看完,再回来搞这些边边角角的东西。
2019-08-06
共3条回复

Node.js+Express+Koa2+Nest.js 开发服务端

从入门到实战,一站式掌握 Node.js+Express+Koa2

4051 学习 · 2006 问题

查看课程