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 面向对象编程基础:封装
Aug 21 Javascript
巧用replace将文字表情替换为图片
Apr 17 Javascript
在页面加载完成后通过jquery给多个span赋值
May 21 Javascript
javascript中parseInt()函数的定义和用法分析
Dec 20 Javascript
jQuery+html5+css3实现圆角无刷新表单带输入验证功能代码
Aug 21 Javascript
每天一篇javascript学习小结(面向对象编程)
Nov 20 Javascript
浅谈jquery中next与siblings的区别
Oct 27 Javascript
jQuery滚动插件scrollable.js用法分析
May 25 jQuery
微信小程使用swiper组件实现图片轮播切换显示功能【附源码下载】
Dec 12 Javascript
vue计算属性和监听器实例解析
May 10 Javascript
JS数组方法slice()用法实例分析
Jan 18 Javascript
Node.js API详解之 util模块用法实例分析
May 09 Javascript
深入理解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翻页类
2009/06/01 PHP
php牛逼的面试题分享
2013/01/18 PHP
smarty模板引擎中自定义函数的方法
2015/01/22 PHP
PHP 中 DOMDocument保存xml时中文出现乱码问题的解决方案
2016/09/19 PHP
Yii2.0中使用js异步删除示例
2017/03/10 PHP
PHP实现打包zip并下载功能
2018/06/12 PHP
JavaScript使用指针操作实现约瑟夫问题实例
2015/04/07 Javascript
JavaScript中指定函数名称的相关方法
2015/06/04 Javascript
AngularJs基本特性解析(一)
2016/07/21 Javascript
使用do...while的方法输入一个月中所有的周日(实例代码)
2016/07/22 Javascript
html5+CSS 实现禁止IOS长按复制粘贴功能
2016/12/28 Javascript
jQuery Json数据格式排版高亮插件json-viewer.js使用方法详解
2017/06/12 jQuery
使用JS实现气泡跟随鼠标移动的动画效果
2017/09/16 Javascript
js使用ajax传值给后台,后台返回字符串处理方法
2018/08/08 Javascript
Layui数据表格之获取表格中所有的数据方法
2018/08/20 Javascript
使用 node.js 模仿 Apache 小部分功能
2019/07/07 Javascript
返回上一个url并刷新界面的js代码
2020/09/12 Javascript
Python中的生成器和yield详细介绍
2015/01/09 Python
Python中的数学运算操作符使用进阶
2016/06/20 Python
Python实现合并excel表格的方法分析
2019/04/13 Python
keras 自定义loss损失函数,sample在loss上的加权和metric详解
2020/05/23 Python
python计算auc的方法
2020/09/09 Python
python 如何读、写、解析CSV文件
2021/03/03 Python
HTML5不支持frameset的两种解决方法
2016/11/14 HTML / CSS
利用指针变量实现队列的入队操作
2012/04/07 面试题
SQL里面IN比较快还是EXISTS比较快
2012/07/19 面试题
海飞丝的广告词
2014/03/20 职场文书
文明礼貌演讲稿
2014/05/12 职场文书
学校安全教育月活动总结
2014/07/07 职场文书
慈善捐赠倡议书
2014/08/30 职场文书
体育运动会广播稿
2014/10/05 职场文书
倡议书作文
2015/01/19 职场文书
五年级语文教学反思
2016/03/03 职场文书
2019最新版股权转让及委托持股协议书范本
2019/08/07 职场文书
Golang二维数组的使用方式
2021/05/28 Golang
JavaWeb Servlet开发注册页面实例
2022/04/11 Java/Android