React+react-dropzone+node.js实现图片上传的示例代码


Posted in Javascript onAugust 23, 2017

本文将会用typescript+react+react-dropzone+express.js实现前后端上传图片。当然是用typescript需要提前下载相应的模块,在这里就不依依介绍了。

第一步,配置tsconfig.js

"compilerOptions": { 
      "outDir": "./public/", 
      "sourceMap": true, 
      "noImplicitAny": true, 
      "module": "commonjs", 
      "target": "es5", 
      "jsx": "react" ,
      "noImplicitAny": false,
      "suppressImplicitAnyIndexErrors": true
  },
  "files": [ "./views/home/main.tsx" ],
  "exclude": [
    "node_modules"
  ]
}

2.配置webpack

var path = require('path');
var webpack = require('webpack');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var HtmlWebpackPlugin = require('html-webpack-plugin');
var title = {
  home: '首页',
}
module.exports = {
  entry: {
    home: [
      'babel-polyfill',
      './views/home/main.tsx'
    ],
    common: ['react','babel-polyfill']
  },
  output: {
    path: path.join(__dirname, 'views/wap'),
    filename: '[name].js',
    chunkFilename: '[id].build.js?[chunkhash]',
    publicPath: '/views/wap/',
  },
  module: {
    loaders: [
      { 
        test: /\.tsx?$/, 
        loader: 'ts-loader' 
      },
      {
        test: /\.(less|css)$/,
        loader: ExtractTextPlugin.extract('style', 'css!less'),
      },
      {     
       test:/\.(js|jsx)?$/,
       loader:'babel',
       exclude:/node_modules/,
       query:{compact:false,presets:['es2015','react','stage-0','stage-1','stage-2']}
      },
      {
        test: /\.(png|jpg|gif)?$/,
        loaders: ['url?limit=8192&name=[name]_[sha512:hash:base64:7].[ext]'],
      },
      {
        test: /\.(eot|woff|ttf|svg)$/,
        loader: 'file?limit=81920&name=[name]_[sha512:hash:base64:7].[ext]'
      },
    ]
  },
  resolve: {
    root: ['node_modules'],
    extensions: ['', '.js', '.jsx', '.html', '.json','.ts', '.tsx'],
    modulesDirectories: ['node_modules'],
    alias: {}
  },
  externals: {},
  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': '"production"'
    }),
    new webpack.HotModuleReplacementPlugin(),
    new ExtractTextPlugin('[name].[contenthash:20].css'),
    new webpack.optimize.UglifyJsPlugin({
      compress: {warnings: false}
    }),
    new webpack.optimize.CommonsChunkPlugin('common', 'common.js'),
      new HtmlWebpackPlugin(
      {
         title: "",
         template: path.join(path.resolve(__dirname),'views/wap/myApp.html'), //模板文件
         inject:'body',
         hash:true,  //为静态资源生成hash值
         minify:{  //压缩HTML文件
          removeComments:false,  //移除HTML中的注释
          collapseWhitespace:false  //删除空白符与换行符
         }
      }
      )
  ]
};

3.react-dropzone

import * as Dropzone from 'react-dropzone';

<Dropzone  accept="image/jpeg, image/png"
      onDrop={(accepted, rejected) => { this.setState({ accepted, rejected });this.drop(accepted[0].preview) }}
      style={{width:"100%",height:"120px",background:"#f2f2f2","padding-top":'90px',"cursor":"pointer","box-sizing":"content-box"}} >
</Dropzone>

accept:表示图片的接受类型

onDrop代表图片加载以后触发

accepted:表示加载图片成功后相关信息,打印出来如下:

React+react-dropzone+node.js实现图片上传的示例代码

rejected:表示加载图片失败后,相关信息:

React+react-dropzone+node.js实现图片上传的示例代码

4.图片处理、上传

新建一个drop方法在触发onDrop后。

drop(src : any) : any{
    const that = this;
    let img = src;
    let image = new Image();
    image.crossOrigin = 'Anonymous';
    image.src = img;
    image.onload = function(){
      let base64 = that.getBase64Image(image);
      that.upLoadImg({imgData:base64})
    }
}

在这里我们使用base64传递,所以我们需要把图片转成base64,定义getBase64Image处理

getBase64Image(img :any) : string {
    let canvas = document.createElement("canvas");
    canvas.width = img.width;
    canvas.height = img.height;
    let ctx = canvas.getContext("2d");
    ctx.drawImage(img, 0, 0, img.width, img.height);
    let ext = img.src.substring(img.src.lastIndexOf(".")+1).toLowerCase();
    let dataURL = canvas.toDataURL("image/"+ext);
    return dataURL;
}

最终返回的是处理后图片的地址,然后上传

async upLoadImg(params : object) : Promise<any>{
    let res = await axios.post('http://localhost:3000/upLoadImg',params);
}

5.node部分

router/index.js

var express = require('express');
var router = express.Router();
var rf = require('fs');
var SetImg = require('./controller/uploadImg');
var setImg = new SetImg;
router.post('/upLoadImg',setImg.setUploadImg);
module.exports = router;

./controller/uploadImg.js

var rf = require('fs');
class SetImg {
  setUploadImg(req, res, next) {
    let imgData = req.body.imgData;
    let base64Data = imgData.replace(/^data:image\/\w+;base64,/, "");
    let dataBuffer = new Buffer(base64Data, 'base64');
    let timer = Number( new Date() );
    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"});
      }
    });
  }
}
module.exports = SetImg;

拿到图片后先进行格式转换,然后将图片写入到本地,返回图片路径。

import * as React from 'react';
import * as ReactDom  from 'react-dom';

import * as Dropzone from 'react-dropzone';
import * as axios from 'axios';

import './main.less';

declare var document;
declare var Image;
class ImgUpload extends React.Component<any,any> {
  constructor(){
    super()
    this.state = {
     accepted: [],
     rejected: []
    }
  }
  public drop(src : any) : any{
    const that = this;
    let img = src;
    let image = new Image();
    image.crossOrigin = 'Anonymous';
    image.src = img;
    image.onload = function(){
      let base64 = that.getBase64Image(image);
      console.log(base64)
      that.upLoadImg({imgData:base64})
    }
  }
  //转base64
  public getBase64Image(img :any) : string {
    let canvas = document.createElement("canvas");
    canvas.width = img.width;
    canvas.height = img.height;
    let ctx = canvas.getContext("2d");
    ctx.drawImage(img, 0, 0, img.width, img.height);
    let ext = img.src.substring(img.src.lastIndexOf(".")+1).toLowerCase();
    let dataURL = canvas.toDataURL("image/"+ext);
    return dataURL;
  }
  public async upLoadImg(params : object) : Promise<any>{
    let res = await axios.post('http://localhost:3000/upLoadImg',params);

  }
  render(){
    const that = this;
    let imgs;
    if(this.state.accepted.length > 0){
      imgs = (
        <ul>
          {this.state.accepted.map( (f) => {
            return <img key={f.name} src={f.preview} />
          })}
        </ul>
      )
    }
    return (
      <div>
        <div className="wrap">
          <Dropzone
          accept="image/jpeg, image/png"
          onDrop={(accepted, rejected) => { console.log(accepted);console.log(rejected);this.setState({ accepted, rejected });this.drop(accepted[0].preview) }}
          style={{width:"100%",height:"120px",background:"#f2f2f2","padding-top":'90px',"cursor":"pointer","box-sizing":"content-box"}}
           >
            <p className="upload">请添加主题图片</p>
          </Dropzone>
        </div>
        <div className="show">{imgs}  
        </div> 
      </div>
      
    )
  }

}
ReactDom.render(
  <ImgUpload />,
  document.getElementById('app')
)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript数组使用调用方法汇总
Dec 08 Javascript
jquery URL参数判断,确定菜单样式
May 31 Javascript
jquery form 加载数据示例
Apr 21 Javascript
jquery判断页面网址是否有效的两种方法
Dec 11 Javascript
原生js实现类似fullpage的单页/全屏滚动
Jan 22 Javascript
快速使用node.js进行web开发详解
Apr 26 Javascript
jQuery实现 RadioButton做必选校验功能
Jun 15 jQuery
React学习笔记之事件处理(二)
Jul 02 Javascript
ES6模块化的import和export用法方法总结
Aug 08 Javascript
微信小程序实现简单文字跑马灯
May 26 Javascript
微信小程序将页面按钮悬浮固定在底部的实现代码
Oct 29 Javascript
Vue操作Storage本地化存储
Apr 29 Vue.js
深入理解React中何时使用箭头函数
Aug 23 #Javascript
自定义类似于jQuery UI Selectable 的Vue指令v-selectable
Aug 23 #jQuery
JS数组交集、并集、差集的示例代码
Aug 23 #Javascript
关于Vue实现组件信息的缓存问题
Aug 23 #Javascript
详解webpack进阶之loader篇
Aug 23 #Javascript
Vue中定义全局变量与常量的各种方式详解
Aug 23 #Javascript
基于JavaScript实现带数据验证和复选框的表单提交
Aug 23 #Javascript
You might like
PHP控制网页过期时间的代码
2008/09/28 PHP
php数据库配置文件一般做法分享
2012/07/07 PHP
php生成随机数的三种方法
2014/09/10 PHP
PHP中捕获超时事件的方法实例
2015/02/12 PHP
php实现短信发送代码
2015/07/05 PHP
Thinkphp和onethink实现微信支付插件
2016/04/13 PHP
laravel 执行迁移回滚示例
2019/10/23 PHP
javascript学习之闭包分析
2010/12/02 Javascript
js和html5实现手机端刮刮卡抽奖效果完美兼容android/IOS
2013/11/18 Javascript
jQuery制作可自定义大小的拼图游戏
2015/03/30 Javascript
jquery实现的美女拼图游戏实例
2015/05/04 Javascript
javascript实现简单的进度条
2015/07/02 Javascript
js跨域请求的5中解决方式
2015/07/02 Javascript
基于BootStrap Metronic开发框架经验小结【七】数据的导入、导出及附件的查看处理
2016/05/12 Javascript
jQuery页面加载初始化的3种方法(推荐)
2016/06/02 Javascript
codeMirror插件使用讲解
2017/01/16 Javascript
微信小程序 按钮滑动的实现方法
2017/09/27 Javascript
AngularJS 将再发布一个重要版本 然后进入长期支持阶段
2018/01/31 Javascript
JS将时间秒转换成天小时分钟秒的字符串
2019/07/10 Javascript
Vue项目利用axios请求接口下载excel
2020/11/17 Vue.js
Python3读取zip文件信息的方法
2015/05/22 Python
Python实现购物车购物小程序
2018/04/18 Python
Django如何简单快速实现PUT、DELETE方法
2019/07/24 Python
python爬虫项目设置一个中断重连的程序的实现
2019/07/26 Python
Python实现微信翻译机器人的方法
2019/08/13 Python
Python常驻任务实现接收外界参数代码解析
2020/07/21 Python
css3 box-sizing属性使用参考指南
2013/01/08 HTML / CSS
CSS3制作漂亮的照片墙的实现代码
2016/06/08 HTML / CSS
CSS3 border-radius圆角的实现方法及用法详解
2020/09/14 HTML / CSS
friso美素佳儿官方海外旗舰店:荷兰原产原罐
2017/07/03 全球购物
IWOOT美国:新奇的小玩意
2018/04/27 全球购物
令人印象深刻的自荐信
2014/05/25 职场文书
商场促销活动策划方案
2014/08/18 职场文书
查摆问题对照检查材料
2014/08/28 职场文书
幼儿园感恩节活动方案2014
2014/10/11 职场文书
学校财务管理制度
2015/08/04 职场文书