1 访问网址 https://cnodejs.org/api 可以调取api

2.//该body-parser 可以将请求的body数据,转变成 json 格式数据;
//express-session 用于在服务器端存放的session
//query-string 用于转换 url 后面的请求参数 转换成 json 格式

npm i body-parser express-session query-string -S

bodyParser中间件的研究

3 使用方法:

3.1 server.js 主程序:

const express = require('express')
const ReactSSR = require('react-dom/server'); const bodyParser = require('body-parser');//转换成json
const session = require('express-session');//服务端保存数据 const fs = require('fs')
const path = require('path')
const app = express(); app.use(bodyParser.json());//把请求中的数据 转成 req.body 上的数据
app.use(bodyParser.urlencoded({ extended:false})); //表单提交 转换成 req.body上的数据
app.use(session({ //没有做数据库,放在了内存中
maxAge:10*60*1000, //有效期
name:'tid', //session 会给浏览器一个 cookie id
resave:false, //每次请求是否申请一个cookie id
saveUninitialized:false,
secret:'react conde class' //加密
})) app.use('/api/user',require('./util/handle-logim'));
app.use('/api',require('./util/proxy')) const isDev = process.env.NODE_ENV === 'development';
if(!isDev){
const serverEntry = require('../dist/server-entry').default;
const template = fs.readFileSync(path.join(__dirname, '../dist/index.html'), 'utf8')
app.use('/public', express.static(path.join(__dirname, '../dist')));
app.get('*', function (req, res) {
const appString = ReactSSR.renderToString(serverEntry);
res.send(template.replace('<!--app-->',appString))
})
}else{
const devStatic = require('./util/dev.static.js');
   devStatic(app); app.listen(3333, function () {
console.log('server is listening on 3333')
})

3.2 login的登陆逻辑:

//login.js
//因为要把登陆的信息放在服务器session中,不是直接的调取返回数据,所以要单独处理登陆接口
const router = require('express').Router();
const axios = require('axios');
//文档定义 以下 api 路径均以 https://cnodejs.org/api/v1 为前缀
const baseUrl = 'http://cnodejs.org/api/v1';
// 文档中规定 post/accesstoken 验证 accessToken 的正确性;
// 接受 post参数 accesstoken 用户的 accessToken
router.post('/login',function(req,res){ //执行登陆接口
axios.post(`${baseUrl}/accesstoken`,{ //post /accesstoken 验证 accessToken 的正确性
//接收 post 参数 -- accesstoken String 用户的 accessToken
accesstoken:req.body.accessToken //把用户传递过来的 accesstoken 传给api;注意api中的 accesstoken 用的不是驼峰
}).then(resp=>{
if(resp.status == 200 && resp.data.success){
//把登陆的信息保存到 session 中,下次请求的时候就可以通过 session 获取到
req.session.user = { //在seesion上保存 user 的数据,其中 accessToken 是用户传递过来的所以可以直接使用
accessToken:req.body.accessToken,
loginName:resp.data.loginname, //loginname,id,vul等数据是返回来的
id:resp.data.id,
avatarUrl: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;

3.3 proxy.js

//把用户请求数据的接口,全部代理出去
const axios = require('axios')
const querystring = require('query-string') const baseUrl = 'http://cnodejs.org/api/v1' module.exports = function (req, res, next) { //抛出一个函数
const path = req.path;
const user = req.session.user || {} //判断用户有没有登陆
const needAccessToken = req.query.needAccessToken //是否需要 accesstoken,请求参数 放在 url?后面
//如果url中规定需要 token ,并且session中没有 token
if (needAccessToken && !user.accessToken) {
res.status(401).send({
success: false,
msg: 'need login'
})
} //不能直接使用query,比如url上可能携带,是否需要token的参数 needAccessToken;
const query = Object.assign({}, req.query, {
accesstoken: (needAccessToken && req.method === 'GET') ? user.accessToken : ''
})
if (query.needAccessToken) delete query.needAccessToken //如果有needToken 则删掉 axios(`${baseUrl}${path}`, {
method: req.method, // `method` 是创建请求时使用的方法,默认是 get
params: query, // `params` 是即将与请求一起发送的 URL 参数
  //使用stringify转换前的格式是:{'accesstoken':'xxx'},转换后是 'accesstoken'='xxx'
data: querystring.stringify(Object.assign({}, req.body, { // `data` 是作为请求主体被发送的数据
accesstoken: (needAccessToken && req.method === 'POST') ? user.accessToken : ''
})),
headers: {//避免 cnodejs 有的接口无法获取对应的数据格式 有的接口使用 from-data
'Content-Type': 'application/x-www-form-urlencoded'
}
}).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: '未知错误'
})
}
})
}

执行 npm run dev:server 然后在chrome 浏览器中使用 postman插件进行 url 请求接口测试。

页面上测试请求接口

import React from 'react'
import axios from 'axios' /* eslint-disable */ /*表示中间的代码不需要eslint去检测*/
export default class TestApi extends React.Component { getTopics() {
axios.get('/api/topics')
.then(resp => {
console.log(resp)
}).catch(err => {
console.log(err)
})
} login() {
axios.post('/api/user/login', {
accessToken: 'ef35af2e-95b4-4062-badc-419d3b'//登陆网站,我的页面获取
}).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>
)
}
}
/* eslint-enable */
config.devServer = {
host: '0.0.0.0',
compress: true,
port: '8888',
contentBase: path.join(__dirname, '../dist'),
hot: true,
overlay: {
errors: true
},
publicPath: '/public/',
historyApiFallback: {
index: '/public/index.html'
},
proxy: { //在webpack.config.client.js 文件中配置本地服务器的路径
'/api': 'http://localhost:3333'
}
}
//这样在客户端访问的接口,可以代理到本地服务器上

webpack 配置react脚手架(六):api的更多相关文章

  1. webpack 配置react脚手架(三):eslint 及优化

    首先谨记 eslint的官网:  http://eslint.cn/ 1 安装eslint  npm i eslint -D 2.在根目录下新建文件 .eslintrc { "extends ...

  2. webpack 配置react脚手架(二):热更新

    下面继续配置 webpack dev server    hot module replacement: 首先配置dev-server     安装     npm i webpack-dev-ser ...

  3. webpack 配置react脚手架

    1 react 基本js文件: import React from 'react'; import ReactDOM from 'react-dom'; import App from './App. ...

  4. webpack 配置react脚手架(五):mobx

    1.  配置项.使用mobx,因为语法时es6-next,所以先配置 .babelrc 文件 { "presets": [ ["es2015", { " ...

  5. webpack 配置react脚手架(四):路由配置

    1. 由于 react-router 是集成了 react-router-dom 和 react-router-native的一起的,所以这里要使用的是 react-router-dom, 2. 安装 ...

  6. [webpack] 配置react+es6开发环境

    写在前面 每次开新项目都要重新安装需要的包,简单记录一下. 以下仅包含最简单的功能: 编译react 编译es6 打包src中入口文件index.js至dist webpack配置react+es6开 ...

  7. 使用webpack配置react并添加到flask应用

    学习react,配置是很痛苦的一关,虽然现在有了create-react-app这样方便的工具,但是必须要自己配置一遍,才能更好地进行项目开发. 首先要明确一个概念:react的文件必须经过编译才能被 ...

  8. webpack配置React开发环境(上)

    Webpack 是一个前端资源加载/打包工具,我们部门的一条主要技术栈就是Webpack+React+ES6+node,虽然之前自己做个人项目也接触好多次Webpack,但是自己并没有研读总结过Web ...

  9. 基于webpack的react脚手架

    一.前言:react的cli开发模式太过于简单,好多东西都要自己配置 二.这里有个简单的配置,可以直接上手开发(不熟悉webpack和npm的绕路),已经完成的配置如下 1:默认ejs模板 2:编译l ...

随机推荐

  1. 关于反向生成url

    1.模板渲染 <form action="{% url "bieming" 参数 %}" > <input type="text&q ...

  2. SQL触发器中的inserted表和deleted表

    开发也有年头了,但是触发器确实用的比较少,但是无容置疑触发器确实不错, 最近项目要求需要用到的触发器特别多.频繁,觉得很有必要记录和积累下. 在触发器语句中用两个特殊的表一个是deleted表和ins ...

  3. Linux如何查看进程、杀死进程、启动进程

    1.查看进程:ps命令 下面的命令还没实践,仅仅供你参考:可以用man ps查看格式,只不过是一个小工具而已! ps a 显示现行终端机下的所有程序,包括其他用户的程序.    ps -A 显示所有程 ...

  4. Java 中的并发工具类

    Java 中的并发工具类 CountDownLatch public class JoinCountDownLatchTest { public static void main(String[] a ...

  5. Java常用命令:jps、jstack、jmap、jstat(带有实例教程)

      版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u013310517/article/details/80990924 查看Java进程:jps ...

  6. myisam和innodb的区别,java事务不起作用原因

    myisam:只支持表级锁.不支持事务.方便移植.该类型是mysql默认表存储类型 innodb:支持表级锁和行级锁.支持事务. 如果你的事务不起作用,很可能是用了myisam存储引擎,检查数据表引擎 ...

  7. MacBook Pro 安装composer及Yii2.0

    最近想看看Yii的一些东西,需要安装一下composer curl -sS https://getcomposer.org/installer | php 此操作会下载最新版本到当前的目录下 然后将下 ...

  8. Python 帮你玩微信跳一跳 GitHub Python脚本

    前言想自己搞游戏小程序的 在github 有人已经利用 python程序, 通过adb 获取不同型号安卓手机的系统截图,然后通过计算小人与目标位置距离之后得到准确的触摸时间,再通过 开发者模式里的 a ...

  9. Identityserver4证书

      dotnet应用用IdentityServer4做了登陆的功能,本地运行没有问题,部署到服务器上面就出现上面的问题,打开服务器的日志记录开关,获取到下面的异常信息.原来是     通过分析日志信息 ...

  10. iOS - OC 使用运行时来获取并修改类

    前言:          Objective C的runtime技术功能非常强大,能够在运行时获取并修改类的各种信息,包括获取方法列表.属性列表.变量列表,修改方法.属性,增加方法,属性等等,本文对相 ...