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 相关文章推荐
js string 转 int 注意的问题小结
Aug 15 Javascript
js动态生成Html元素实现Post操作(createElement)
Sep 14 Javascript
js中unicode转码方法详解
Oct 09 Javascript
vue多级多选菜单组件开发
Sep 08 Javascript
jQuery使用eraser.js插件实现擦除、刮刮卡效果的方法【附eraser.js下载】
Apr 28 jQuery
element ui里dialog关闭后清除验证条件方法
Feb 26 Javascript
微信小程序中使用ECharts 异步加载数据实现图表功能
Jul 13 Javascript
vue-cli3.0 脚手架搭建项目的过程详解
Oct 19 Javascript
深入koa-bodyparser原理解析
Jan 16 Javascript
django js 实现表格动态标序号的实例代码
Jul 12 Javascript
vue路由守卫及路由守卫无限循环问题详析
Sep 05 Javascript
vue引入Excel表格插件的方法
Apr 28 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
异世界新番又来了,同样是从零开始,男主的年龄降到5岁
2020/04/09 日漫
drupal 代码实现URL重写
2011/05/04 PHP
smarty中英文多编码字符截取乱码问题解决方法
2014/10/28 PHP
基于jquery的获取浏览器窗口大小的代码
2011/03/28 Javascript
jquery 选项卡效果 新手代码
2011/07/08 Javascript
JavaScript子窗口ModalDialog中操作父窗口对像
2012/12/11 Javascript
jQuery Mobile 导航栏代码
2013/11/01 Javascript
jQuery操作cookie方法实例教程
2014/11/25 Javascript
JavaScript实现选择框按比例拖拉缩放的方法
2015/08/04 Javascript
AngularJS 指令的交互详解及实例代码
2016/09/14 Javascript
react高阶组件经典应用之权限控制详解
2017/09/07 Javascript
VUE在for循环里面根据内容值动态的加入class值的方法
2018/08/12 Javascript
微信小程序如何使用globalData的方法
2019/06/06 Javascript
js设置鼠标悬停改变背景色实现详解
2019/06/26 Javascript
微信小程序npm引入vant-weapp的踩坑记录
2019/08/01 Javascript
JS工厂模式开发实践案例分析
2019/10/17 Javascript
node.js文件操作系统实例详解
2019/11/05 Javascript
JavaScript ECMA-262-3 深入解析(一):执行上下文实例分析
2020/04/25 Javascript
Nuxt的动态路由和参数校验操作
2020/11/09 Javascript
详细介绍Python的鸭子类型
2016/09/12 Python
Python中操作mysql的pymysql模块详解
2016/09/13 Python
Python实现螺旋矩阵的填充算法示例
2017/12/28 Python
Python中循环后使用list.append()数据被覆盖问题的解决
2018/07/01 Python
python跳过第一行快速读取文件内容的实例
2018/07/12 Python
python实现指定字符串补全空格、前面填充0的方法
2018/11/16 Python
Python实现简易过滤删除数字的方法小结
2019/01/09 Python
python解析yaml文件过程详解
2019/08/30 Python
Python3.x+迅雷x 自动下载高分电影的实现方法
2020/01/12 Python
python爬虫可以爬什么
2020/06/16 Python
Python如何将将模块分割成多个文件
2020/08/04 Python
纯CSS3实现运行时钟的示例代码
2021/01/25 HTML / CSS
优秀应届生推荐信
2013/11/09 职场文书
大学生的创业计划书就该这么写
2014/01/30 职场文书
责任书范本
2014/08/25 职场文书
Python基础之教你怎么在M1系统上使用pandas
2021/05/08 Python
Python selenium的这三种等待方式一定要会!
2021/06/10 Python