从0搭建前端项目架构-第六篇cnode代理

201 阅读1分钟

cnode代理实现

  • 安装一下包
    npm i body-parser express-session query-string -S
  • 在server/server.js中配置下
    ...省略
    const bodyParser= require('body-parser')
    const session = require('express-session')
    
    app.use(bodyParser.json())
    app.use(bodyParser.urlencoded({extended:false})
    
    app.use(session({
        maxAge:60*10*1000,
        name:'tid',
        resave:false,
        saveUninitialized:false,
        secret:'react cnode'
    }))
  • 在server/util下创建handle-login.js来代理登陆api
    const router = require('express').Router()
    const axios = require('axios')
    
    const baseUrl = 'http://cnodejs.org/api/v1'
    
    router.post('/login',(req,res,next)=>{
        axios.post(`${baseUrl}/accesstoken`,{
            accesstoken:req.body.accessToken
        })
        .then((resp => {
            if(res.status == 200 && resp.data.success){
                req.session.user= {
                    accessToken:req.body.accessToken,
                    loginName:resp.data.loginname,
                    id:resp.data.id,
                    avatarrUrl:resp.data.avatar_url
                }
                res.json({
                    success:'true',
                    data:resp.data
                })
            }
    
        }))
        .catch(err=>{
            if(err.response){
                res.json({
                    success:'false',
                    data:err.response
                })
            }else{
                next(err)
            }
        })
    })
    
    module.exports = router;
  • 在server/util下创建proxy.js来代理cnode的api
    const axios = require('axios')
    const baseUrl = 'https://cnodejs.org/api/v1'
    module.exports = ((req,res,next) => {
        const path = req.path;
        const user = req.session.user || {};
        const needAccessToken = req.query.needAccessToken;
    
        if(needAccessToken && user.needAccessToken){
            res.status(401).send({
                success:'false',
                msg:'need login'
            })
        }
    
        const query  = Object.assign({},req.query)
    
        if(query.needAccessToken) delete query.needAccessToken
    
        axios(`${baseUrl}${path}`,{
            method:req.method,
            params:query,
            data:Object.assign({},req.body,{
                accesstoken:user.accessToken
            }),
            headers:{
                'Content-Type':'application/x-www-form-urlencode'
            }
        }).then(resp=>{
            if(resp.status ==200){
                res.send(resp.data)
            }else{
                res.status(resp.status).send(resp.data)
            }
        }).catch(err=>{
            if(err.response){
                res.status(500).send(err.response.data)
            }else{
                res.status(500).send({
                    success:'false',
                    msg:'未知错误'
                })
            }
        })
    })
  • 在server/server.js中引入上面两个,必须放在服务端渲染配置前
    app.use('/api/user',require('./util/handle-login'))
    app.use('/api',require('./util/proxy'))

这样就配置好了。我们使用postman测试一下。

可以看到,cnode代理就实现好了。

调试接口代理

  • 在client/views下新建test文件夹,在test文件夹下新建api-test.js
    import React from 'react'
    import axios from 'axios'
    export default class TestApi extends React.Component {
    
        getTopics = () => {
            axios.get('/api/topics')
            .then(resp=>{
                console.log(resp)
            })
            .catch(err=>{
                console.log(err)
            })
        }
    
        login = () => {
            axios.get('/api/user/login',{
                accessToken:'b9cc588e-555a-4516-ad9e-54848201603f'
            })
            .then(resp=>{
                console.log(resp)
            })
            .catch(err=>{
                console.log(err)
            })
        }
    
        markAll = () => {
            axios.post('/api/message/mark_all?needAccessToken=true')
            .then(resp=>{
                console.log(resp)
            })
            .catch(err=>{
                console.log(err)
            })
        }
        render(){
            return(
                <div>
                    <button onClick={this.getTopics}>topics</button>
                    <button onClick={this.login}>login</button>
                    <button onClick={this.markAll}>markAll</button>
                </div>
            )
        }
    }
  • 在client/config/router.jsx下引入这个测试文件
    import TestApi from '../views/test/api-test';
    
    <Route path="/test" component={TestApi} key='test'  />
  • 重启客户端和服务端,调试接口 可以看到接口成功了