Maison  >  Article  >  interface Web  >  Terminez la vérification de la connexion à l'aide de node.js+captchapng+jsonwebtoken

Terminez la vérification de la connexion à l'aide de node.js+captchapng+jsonwebtoken

巴扎黑
巴扎黑original
2017-08-18 10:34:302239parcourir

Cet article présente principalement l'exemple de node.js+captchapng+jsonwebtoken pour implémenter la vérification de connexion. Il a une certaine valeur de référence. Ceux qui sont intéressés peuvent en apprendre davantage.

En ce qui concerne la vérification de connexion, tout le monde peut certainement y penser. Le code de vérification est 12306. 12306 s'est donné beaucoup de mal pour prévenir la fraude aux billets, et le code de vérification est devenu de plus en plus difficile à identifier, et éventuellement même les humains pourraient ne pas être en mesure de l'identifier.

Aujourd'hui, l'éditeur vous expliquera comment implémenter le code de vérification d'image dans le nœud et utiliser un jeton pour vérifier la connexion. En étudiant cet article, vous apprendrez :

1. Utilisez captchapng pour générer le code de vérification d'image

2. Utilisez jsonwebtoken pour implémenter la vérification de connexion

1 , Génération de code de vérification d'image (tous les codes à la fin)

Tout d'abord, jetons un coup d'œil au processus Dans la première étape, le serveur doit générer aléatoirement un ensemble de quatre. chiffres.

La deuxième étape consiste à dessiner ces quatre chiffres sur toile pour générer une image.

La troisième étape consiste à enregistrer ces quatre chiffres à des fins de comparaison lorsque l'utilisateur renvoie les données.

Alors, où le sauvegarder ? Évidemment, afin de distinguer les utilisateurs, il est plus sûr de les enregistrer en session.

La première étape est d'avoir une page de connexion. Ici, nous utilisons toujours React,

login.tsx


import * as React from 'react'
import * as ReactDom from 'react-dom'
import {Link, browserHistory} from 'react-router';
import * as axios from 'axios';
export default class Login extends React.Component<any,any>{
  constructor(props){
    super(props)
    this.state = {
      userName : &#39;&#39;,
      password : &#39;&#39;,
      yzNoId  : &#39;&#39;,
      hash : Math.random()
    }
  }
  handleUserName(e) : any {
    this.setState({
      userName : e.target.value
    })
  }
  handlePassword(e) : any {
    this.setState({
      password : e.target.value
    })
  }
  handleYzId(e) : any {
    this.setState({
      yzNoId : e.target.value
    })
  }
  render(){
    const { userName, password, yzNoId } = this.state;
    return(
      <p>
        <p className="nav-wrap">
          <ul className="nav">
            <li><Link to="/home">首页</Link></li>
            <li><Link to="/imgLoad">上传</Link></li>
            <li><Link to="/login">登陆</Link></li>
          </ul>
        </p>
        <p className="content">
          <p className="login-warp">
            <p>
              <input type="text" className="username" value={userName} onChange={this.handleUserName.bind(this)} placeholder="用户名"/>
            </p>
            <p>
              <input type="text" className="password" value={password} onChange={this.handlePassword.bind(this)} placeholder="密码"/>  
            </p>  
            <p>
              <input type="text" className="yz" value={yzNoId} onChange={this.handleYzId.bind(this)} placeholder="验证码"/>
              <img src={"http://localhost:3000/captcha"} className="yz-img" />  
            </p>
            <p>
              <input type="button" className="submit" value="登陆" onClick={this.sbumit.bind(this,{userName:userName,password:password,captcha:yzNoId})} /> 
            </p>  
          </p>
        </p>
      </p>
    )
  }
}

La page ressemble à ceci


Nous devons envoyer une photo de vérification via le serveur.

router/index.js Ajoutez le code suivant


var Login = require(&#39;./controller/login&#39;);
var login = new Login;
router.get(&#39;/captcha&#39;, login.captcha);
router.post(&#39;/login&#39;,login.loginer);
login是定义在控制器的一个类的实例,captcha,loginer是它的方法。分别是返回验证图片、登录验证。
controller/login.js

var rf = require(&#39;fs&#39;);
var captchapng = require(&#39;captchapng&#39;);
class Login {
  constructor(){}
  captcha(req, res, next) {
    var str = parseInt(Math.random()*9000+1000);  //随机生成数字
    req.session.captcha = str;  // 存入session
    var p = new captchapng(80, 30, str); //生成图片
    p.color(0, 0, 0, 0);
    p.color(80, 80, 80, 255);
    var img = p.getBase64();
    var imgbase64 = new Buffer(img, &#39;base64&#39;);
    res.writeHead(200, {
      &#39;Content-Type&#39;: &#39;image/png&#39;
    });
    res.end(imgbase64);
  }
  loginer(req, res, next) {
    let captcha = req.body.captcha;
    let userName = req.body.userName;
    let password = req.body.password;
    if (captcha != req.session.captcha) {
      res.status(400).send({
        message: &#39;验证码错误&#39;
      });
    }else if(userName == "chenxuehui" && password == "123321"){
      res.json({"code":100,"verson":true,"msg":"登陆成功","token":token});
    }else{
      res.json({"code":0,"verson":false,"msg":"密码错误"});
    }
  }
}
module.exports = Login

La méthode captcha consiste à générer une image contenant quatre chiffres, puis L'image est enregistrée dans la session.

Référencez cette méthode dans router/index.js


router.get(&#39;/captcha&#39;, login.captcha);

C'est-à-dire si on accède à localhost:3000/captcha une image.

Avec cette connexion, nous pouvons obtenir l'image via l'attribut src de l'image, mais lorsque l'on clique sur l'image, elle doit être actualisée, nous devons donc ajouter un événement d'actualisation de clic. Insérez le code suivant dans login.tsx


setHash() {
    this.setState({
      hash : Math.random()
    })
}

La balise img devient également

Copier le code Le code est la suivante :


🎜>
De cette façon, tant que vous cliquez sur img, un hachage sera généré aléatoirement, puis la nouvelle image sera appelée.


Ensuite, nous procédons à la vérification de la connexion.

La méthode de connexion est utilisée pour la vérification de la connexion.


Obtenez les informations de nom d'utilisateur, le mot de passe et le code de vérification de l'utilisateur à des fins de comparaison, et enfin renvoyez des données indiquant si la connexion a réussi.
import * as React from &#39;react&#39;
import * as ReactDom from &#39;react-dom&#39;
import {Link, browserHistory} from &#39;react-router&#39;;
import * as axios from &#39;axios&#39;;
export default class Login extends React.Component<any,any>{
  constructor(props){
    super(props)
    this.state = {
      userName : &#39;&#39;,
      password : &#39;&#39;,
      yzNoId  : &#39;&#39;,
      hash : Math.random()
    }
  }
  public async sbumit(params : any) : Promise<any>{
    let res = await axios.post(&#39;http://localhost:3000/login&#39;,params);
  }
  handleUserName(e) : any {
    this.setState({
      userName : e.target.value
    })
  }
  handlePassword(e) : any {
    this.setState({
      password : e.target.value
    })
  }
  handleYzId(e) : any {
    this.setState({
      yzNoId : e.target.value
    })
  }
  setHash() {
    this.setState({
      hash : Math.random()
    })
  }
  render(){
    const { userName, password, yzNoId } = this.state;
    return(
      <p>
        <p className="nav-wrap">
          <ul className="nav">
            <li><Link to="/home">首页</Link></li>
            <li><Link to="/imgLoad">上传</Link></li>
            <li><Link to="/login">登陆</Link></li>
          </ul>
        </p>
        <p className="content">
          <p className="login-warp">
            <p>
              <input type="text" className="username" value={userName} onChange={this.handleUserName.bind(this)} placeholder="用户名"/>
            </p>
            <p>
              <input type="text" className="password" value={password} onChange={this.handlePassword.bind(this)} placeholder="密码"/>  
            </p>  
            <p>
              <input type="text" className="yz" value={yzNoId} onChange={this.handleYzId.bind(this)} placeholder="验证码"/>
              <img src={"http://localhost:3000/captcha?aaa="+this.state.hash} className="yz-img" onClick={this.setHash.bind(this)} />  
            </p>
            <p>
              <input type="button" className="submit" value="登陆" onClick={this.sbumit.bind(this,{userName:userName,password:password,captcha:yzNoId})} /> 
            </p>  
          </p>
        </p>
      </p>
    )
  }
}


Lorsque l'utilisateur se connecte avec succès, il n'est pas nécessaire de se reconnecter la prochaine fois. Dans le passé, vous pouvez choisir une session ou un cookie. Ici, nous utilisons un jeton. Parce que nous avons désormais implémenté un développement séparé du front-end et du back-end, nous sommes plus enclins à créer une seule page et à utiliser Ajax pour créer des applications. Le token est le plus adapté à ce modèle de développement.


Vérification de connexion au jeton


Le jeton est une chaîne cryptée une fois la connexion réussie, il est renvoyé à l'utilisateur pour stockage. Ensuite, l'utilisateur apportera ce jeton lors de la demande. interface. Nous devons donc chiffrer le jeton.


Json Web Token est spécifiquement conçu pour résoudre ce problème. Le principe ne sera pas expliqué en détail. En fait, il s'agit d'obtenir une chaîne d'une certaine manière puis de la démêler d'une certaine manière. .

La première étape que nous devons faire est

Lorsque l'utilisateur se connecte avec succès, créez un jeton et renvoyez-le à l'utilisateur.


Étape 2 : Une fois que l'utilisateur a obtenu le jeton, il doit enregistrer le jeton localement.


Étape 3 : Nous devons écrire une couche intermédiaire à chaque fois que l'utilisateur le demande, nous vérifions si le jeton porté par l'utilisateur est correct. Les données sont renvoyées correctement, l'avertissement est renvoyé de manière incorrecte.

Les utilisateurs doivent apporter le jeton dans l'en-tête chaque fois qu'ils demandent des données.


Première étape : Toujours contrôleur/login.js



Cette fois, nous ajoutons le jeton de configuration dans la méthode de connexion et revenons à utilisateurs. La méthode setToken est une méthode de définition de jeton.



Étape 2 : Enregistrez une fois que l'utilisateur l'a obtenu.

Dans login.tsx, cela devient comme suit


var rf = require(&#39;fs&#39;);
var jwt = require(&#39;jsonwebtoken&#39;);
var captchapng = require(&#39;captchapng&#39;);
var Tokens = require(&#39;../middleware/token&#39;)
var t = new Tokens;
class Login {
  constructor(){}
  captcha(req, res, next) {
    var str = parseInt(Math.random()*9000+1000);  //随机生成数字
    req.session.captcha = str;  // 存入session
    var p = new captchapng(80, 30, str); //生成图片
    p.color(0, 0, 0, 0);
    p.color(80, 80, 80, 255);
    var img = p.getBase64();
    var imgbase64 = new Buffer(img, &#39;base64&#39;);
    res.writeHead(200, {
      &#39;Content-Type&#39;: &#39;image/png&#39;
    });
    res.end(imgbase64);
  }
  loginer(req, res, next) {
    let captcha = req.body.captcha;
    let userName = req.body.userName;
    let password = req.body.password;
    if (captcha != req.session.captcha) {
      res.status(400).send({
        message: &#39;验证码错误&#39;
      });
    }else if(userName == "chenxuehui" && password == "123321"){
      // 设置token
      var datas = {userName:"chenxuehui"}
        //调用../middleware/token 下方法设置
      var token = t.setToken(&#39;cxh&#39;,300,datas)
      res.json({"code":100,"verson":true,"msg":"登陆成功","token":token});
    }else{
      res.json({"code":0,"verson":false,"msg":"密码错误"});
    }
  }
}

module.exports = Login


Dans la méthode sbumit, nous mettons le jeton dans sesssonstorage.


Étape 3 : Configurez le middleware pour vérifier le jeton à chaque fois qu'il demande l'interface. Si l'analyse réussit, il sera ajouté à l'en-tête de la demande.

./middleware/token.js


import * as React from &#39;react&#39;
import * as ReactDom from &#39;react-dom&#39;
import {Link, browserHistory} from &#39;react-router&#39;;
import * as axios from &#39;axios&#39;;
export default class Login extends React.Component<any,any>{
  constructor(props){
    super(props)
    this.state = {
      userName : &#39;&#39;,
      password : &#39;&#39;,
      yzNoId  : &#39;&#39;,
      hash : Math.random()
    }
  }
  public async sbumit(params : any) : Promise<any>{
    let res = await axios.post(&#39;http://localhost:3000/login&#39;,params);
    if(res.data.verson){
      sessionStorage.setItem(&#39;token&#39;,res.data.token);
      browserHistory.push("/home")
    }
  }
  handleUserName(e) : any {
    this.setState({
      userName : e.target.value
    })
  }
  handlePassword(e) : any {
    this.setState({
      password : e.target.value
    })
  }
  handleYzId(e) : any {
    this.setState({
      yzNoId : e.target.value
    })
  }
  setHash() {
    this.setState({
      hash : Math.random()
    })
  }
  render(){
    const { userName, password, yzNoId } = this.state;
    return(
      <p>
        <p className="nav-wrap">
          <ul className="nav">
            <li><Link to="/home">首页</Link></li>
            <li><Link to="/imgLoad">上传</Link></li>
            <li><Link to="/login">登陆</Link></li>
          </ul>
        </p>
        <p className="content">
          <p className="login-warp">
            <p>
              <input type="text" className="username" value={userName} onChange={this.handleUserName.bind(this)} placeholder="用户名"/>
            </p>
            <p>
              <input type="text" className="password" value={password} onChange={this.handlePassword.bind(this)} placeholder="密码"/>  
            </p>  
            <p>
              <input type="text" className="yz" value={yzNoId} onChange={this.handleYzId.bind(this)} placeholder="验证码"/>
              <img src={"http://localhost:3000/captcha?aaa="+this.state.hash} className="yz-img" onClick={this.setHash.bind(this)} />  
            </p>
            <p>
              <input type="button" className="submit" value="登陆" onClick={this.sbumit.bind(this,{userName:userName,password:password,captcha:yzNoId})} /> 
            </p>  
          </p>
        </p>
      </p>
    )
  }
}


La méthode testToken consiste à vérifier le jeton et setToken consiste à définir le jeton méthode


S'il n'y a pas de demande de connexion, c'est comme ça


在 router/index.js


var express = require('express');
var router = express.Router();
var rf = require('fs');
var Login = require('./controller/login');
var Tokens = require('./middleware/token')
var t = new Tokens;
var login = new Login;
//主页
router.get('/', function(req, res, next) {
  res.render("wap/index")
});
//获取图片验证码
router.get(&#39;/captcha&#39;, login.captcha);
//登录验证
router.post('/login',login.loginer);
//请求数据时 t.testToken 验证token
router.post('/list',t.testToken,function(req, res, next){
  res.json({
    //在请求信息里面拿到数据
    username : req.userInfo.userName,
    success : true,
    result : [
      {
        name:'1111111'
      },
      {
        name :'22222'
      }
    ]
  })
})
module.exports = router;

我们在另一个页面调用list接口试一下


import * as axios from &#39;axios&#39;;
import { transToken } from &#39;../decorator/index&#39;


class Home extends React.Component<any,any>{
  constructor(props){
    super(props)
    this.state = {
      data : &#39;&#39;
    }
  }
  async getList(): Promise<any>{
    let token = sessionStorage.getItem(&#39;token&#39;);
    const config = {
     // 请求头信息
     headers: {&#39;x-access-token&#39;: token}      
    }
    let res = await axios.post(&#39;http://localhost:3000/list&#39;,{},config);
    if(!res.data.success){
      browserHistory.push(&#39;/login&#39;);
      return;
    }
    this.setState({
      data : res.data
    })
  }
  render(){
    const { data } = this.state;
    return(
      <p>
        <p className="nav-wrap">
          <ul className="nav">
            <li><Link to="/home">首页</Link></li>
            <li><Link to="/imgLoad">上传</Link></li>
            <li><Link to="/login">登陆</Link></li>
          </ul>
        </p>
        <p className="content">
          Home
          <span onClick={this.getList.bind(this)}>获取数据</span>
          <p>{
            data ? data.result.map( (val,k) => {
              return <li key = {k}>{val.name}</li>
            }) : null
          }</p>
        </p>
      </p>
      
    )
  }
}
export default Home

当调用getList时,如果此时没有登录res.data.success就会为false,则跳到登录页。

全部代码

node.js

app.js


var express = require(&#39;express&#39;);
var path = require(&#39;path&#39;);
var favicon = require(&#39;serve-favicon&#39;);
var logger = require(&#39;morgan&#39;);
var cookieParser = require(&#39;cookie-parser&#39;);
var bodyParser = require(&#39;body-parser&#39;);
var session = require("express-session");
var ejs = require(&#39;ejs&#39;);

var index = require(&#39;./routes/index&#39;);


var app = express();

// view engine setup
app.set(&#39;views&#39;, path.join(__dirname, &#39;views&#39;));
// app.set(&#39;view engine&#39;, &#39;jade&#39;);
app.engine(&#39;html&#39;, ejs.__express);
app.set(&#39;view engine&#39;, &#39;html&#39;);
app.use(session({
  secret:"dabao",
  resave:false,
  saveUninitialized:true,
  cookie:{}
}));
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, &#39;public&#39;, &#39;favicon.ico&#39;)));
app.use(logger(&#39;dev&#39;));
app.use(bodyParser.json());
app.use(bodyParser({limit: 5000000}));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, &#39;&#39;)));

app.use(&#39;/&#39;, index);


// catch 404 and forward to error handler
app.use(function(req, res, next) {
 var err = new Error(&#39;Not Found&#39;);
 err.status = 404;
 next(err);
});

// error handler
app.use(function(err, req, res, next) {
 // set locals, only providing error in development
 res.locals.message = err.message;
 res.locals.error = req.app.get(&#39;env&#39;) === &#39;development&#39; ? err : {};

 // render the error page
 res.status(err.status || 500);
 res.render(&#39;error&#39;);
});

module.exports = app;

index.js


var express = require('express');
var router = express.Router();
var rf = require('fs');
var Login = require('./controller/login');
var Tokens = require('./middleware/token')
var t = new Tokens;
var login = new Login;
/* GET home page. */
router.get('/', function(req, res, next) {
  res.render("wap/index")
});
router.post('/upLoadImg',function(req,res,next){
  let imgData = req.body.imgData;
  console.log(imgData)
  let base64Data = imgData.replace(/^data:image\/\w+;base64,/, "");
  let dataBuffer = new Buffer(base64Data, 'base64');
  let timer = Number( new Date() );
  console.log(timer)
  rf.writeFile("views/images/artCover"+timer+".png",dataBuffer, function(err) {
    if(err) {
     res.json({"code":400,"verson":false,"msg":err});
    }else {
     res.json({"code":100,"verson":true,"url":"views/src/common/images/artCover/"+timer+".png"});
    }
  });
})
router.get(&#39;/captcha&#39;, login.captcha);
router.post('/login',login.loginer);
router.post('/list',t.testToken,function(req, res, next){
  // 先解析token 
  console.log(req.userInfo)
  res.json({
    username : req.userInfo.userName,
    success : true,
    result : [
      {
        name:'1111111'
      },
      {
        name :'22222'
      }
    ]
  })
})
module.exports = router;

controller/login.js


var rf = require(&#39;fs&#39;);
var jwt = require(&#39;jsonwebtoken&#39;);
var captchapng = require(&#39;captchapng&#39;);
var Tokens = require(&#39;../middleware/token&#39;)
var t = new Tokens;
class Login {
  constructor(){}
  captcha(req, res, next) {
    var str = parseInt(Math.random()*9000+1000);  //随机生成数字
    req.session.captcha = str;  // 存入session
    var p = new captchapng(80, 30, str); //生成图片
    p.color(0, 0, 0, 0);
    p.color(80, 80, 80, 255);
    var img = p.getBase64();
    var imgbase64 = new Buffer(img, &#39;base64&#39;);
    res.writeHead(200, {
      &#39;Content-Type&#39;: &#39;image/png&#39;
    });
    res.end(imgbase64);
  }
  loginer(req, res, next) {
    let captcha = req.body.captcha;
    let userName = req.body.userName;
    let password = req.body.password;
    if (captcha != req.session.captcha) {
      res.status(400).send({
        message: &#39;验证码错误&#39;
      });
    }else if(userName == "chenxuehui" && password == "123321"){
      // 设置token
      var datas = {userName:"chenxuehui"}
      var token = t.setToken(&#39;cxh&#39;,300,datas)
      res.json({"code":100,"verson":true,"msg":"登陆成功","token":token});
    }else{
      res.json({"code":0,"verson":false,"msg":"密码错误"});
    }
  }
}
module.exports = Login

middleware/token.js


var jwt = require(&#39;jsonwebtoken&#39;);

class Tokens {
  constructor(){}
  testToken(req,res,next) {
    var token = req.body.token || req.query.token || req.headers[&#39;x-access-token&#39;];

    if(token) {
      jwt.verify(token, &#39;cxh&#39; , function(err,decoded) {
        if(err) {
          return res.json({success:false,msg:&#39;token错误&#39;})
        }else {
          req.userInfo = decoded;
          next()
        }
      })
    }else {
      return res.status(403).send({success:false,msg:"没有token"})
    }
  }
  setToken(name,time,data) {
    var jwtSecret = name;
    var token = jwt.sign(data, jwtSecret, {
      expiresIn: time
    })
    return token;
  }
}
module.exports = Tokens

react部分

login.tsx


import * as React from &#39;react&#39;
import * as ReactDom from &#39;react-dom&#39;
import {Link, browserHistory} from &#39;react-router&#39;;
import * as axios from &#39;axios&#39;;
export default class Login extends React.Component<any,any>{
  constructor(props){
    super(props)
    this.state = {
      userName : &#39;&#39;,
      password : &#39;&#39;,
      yzNoId  : &#39;&#39;,
      hash : Math.random()
    }
  }
  public async sbumit(params : any) : Promise<any>{
    let res = await axios.post(&#39;http://localhost:3000/login&#39;,params);
    if(res.data.verson){
      sessionStorage.setItem(&#39;token&#39;,res.data.token);
      browserHistory.push("/home")
    }
  }
  handleUserName(e) : any {
    this.setState({
      userName : e.target.value
    })
  }
  handlePassword(e) : any {
    this.setState({
      password : e.target.value
    })
  }
  handleYzId(e) : any {
    this.setState({
      yzNoId : e.target.value
    })
  }
  setHash() {
    this.setState({
      hash : Math.random()
    })
  }
  render(){
    const { userName, password, yzNoId } = this.state;
    return(
      <p>
        <p className="nav-wrap">
          <ul className="nav">
            <li><Link to="/home">首页</Link></li>
            <li><Link to="/imgLoad">上传</Link></li>
            <li><Link to="/login">登陆</Link></li>
          </ul>
        </p>
        <p className="content">
          <p className="login-warp">
            <p>
              <input type="text" className="username" value={userName} onChange={this.handleUserName.bind(this)} placeholder="用户名"/>
            </p>
            <p>
              <input type="text" className="password" value={password} onChange={this.handlePassword.bind(this)} placeholder="密码"/>  
            </p>  
            <p>
              <input type="text" className="yz" value={yzNoId} onChange={this.handleYzId.bind(this)} placeholder="验证码"/>
              <img src={"http://localhost:3000/captcha?aaa="+this.state.hash} className="yz-img" onClick={this.setHash.bind(this)} />  
            </p>
            <p>
              <input type="button" className="submit" value="登陆" onClick={this.sbumit.bind(this,{userName:userName,password:password,captcha:yzNoId})} /> 
            </p>  
          </p>
        </p>
      </p>
    )
  }
}

home.js 获取列表信息


import * as React from &#39;react&#39;
import * as ReactDom from &#39;react-dom&#39;
import {Link, browserHistory} from &#39;react-router&#39;;
import * as axios from &#39;axios&#39;;
class Home extends React.Component<any,any>{
  constructor(props){
    super(props)
    this.state = {
      data : &#39;&#39;
    }
  }
  async getList(): Promise<any>{
    let token = sessionStorage.getItem(&#39;token&#39;);
    const config = {
     // 请求头信息
     headers: {&#39;x-access-token&#39;: token}      
    }
    let res = await axios.post(&#39;http://localhost:3000/list&#39;,{},config);
    if(!res.data.success){
      browserHistory.push(&#39;/login&#39;);
      return;
    }
    this.setState({
      data : res.data
    })
  }
  render(){
    const { data } = this.state;
    return(
      <p>
        <p className="nav-wrap">
          <ul className="nav">
            <li><Link to="/home">首页</Link></li>
            <li><Link to="/imgLoad">上传</Link></li>
            <li><Link to="/login">登陆</Link></li>
          </ul>
        </p>
        <p className="content">
          Home
          <span onClick={this.getList.bind(this)}>获取数据</span>
          <p>{
            data ? data.result.map( (val,k) => {
              return <li key = {k}>{val.name}</li>
            }) : null
          }</p>
        </p>
      </p>
      
    )
  }
}
export default Home

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn