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 相关文章推荐
Mootools 1.2教程 输入过滤第一部分(数字)
Sep 15 Javascript
Jquery 插件开发笔记整理
Jan 17 Javascript
jquery中实现简单的tabs插件功能的代码
Mar 02 Javascript
jquery 如何动态添加、删除class样式方法介绍
Nov 07 Javascript
JS延时提示框实现方法详解
Nov 26 Javascript
JavaScript数据结构与算法之链表
Jan 29 Javascript
Vue.js学习教程之列表渲染详解
May 17 Javascript
基于AngularJS的拖拽文件上传的实例代码
Jul 15 Javascript
基于input框覆盖掉数字英文的实例讲解
Jul 21 Javascript
JS实现字符串中去除指定子字符串方法分析
May 17 Javascript
详解Vue开发微信H5微信分享签名失败问题解决方案
Aug 09 Javascript
layui将table转化表单显示的方法(即table.render转为表单展示)
Sep 24 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 计划任务 检测用户连接状态
2012/03/29 PHP
对字符串进行HTML编码和解码的JavaScript函数
2010/02/01 Javascript
js简单实现用户注册信息的校验代码
2013/11/15 Javascript
快速解决jquery之get缓存问题的最简单方法介绍
2013/12/19 Javascript
node.js中的console.info方法使用说明
2014/12/09 Javascript
javascript实现控制文字大中小显示
2015/04/28 Javascript
jQuery右下角旋转环状菜单特效代码
2015/08/10 Javascript
简单讲解jQuery中的子元素过滤选择器
2016/04/18 Javascript
jQuery简单实现上下,左右滑动的方法
2016/06/01 Javascript
浅析$.getJSON异步请求和同步请求
2016/06/06 Javascript
Javascript类型系统之undefined和null浅析
2016/07/13 Javascript
javascript实现获取图片大小及图片等比缩放的方法
2016/11/24 Javascript
bootstrap导航栏、下拉菜单、表单的简单应用实例解析
2017/01/06 Javascript
JS实现按钮添加背景音乐示例代码
2017/10/17 Javascript
JSON数据中存在单个转义字符“\”的处理方法
2018/07/11 Javascript
VScode格式化ESlint方法(最全最好用方法)
2019/09/10 Javascript
使用JavaScript获取扫码枪扫描得到的条形码的思路代码详解
2020/06/10 Javascript
javascript实现移动端红包雨页面
2020/06/23 Javascript
[05:31]DOTA2上海特级锦标赛主赛事第三日RECAP
2016/03/05 DOTA
举例讲解Python中的算数运算符的用法
2015/05/13 Python
Django自定义用户登录认证示例代码
2019/06/30 Python
python交易记录整合交易类详解
2019/07/03 Python
matplotlib 曲线图 和 折线图 plt.plot()实例
2020/04/17 Python
Keras实现支持masking的Flatten层代码
2020/06/16 Python
python PyAUtoGUI库实现自动化控制鼠标键盘
2020/09/09 Python
详解Python中Pyyaml模块的使用
2020/10/08 Python
Flask-SocketIO服务端安装及使用代码示例
2020/11/26 Python
python文件路径操作方法总结
2020/12/21 Python
10 套华丽的CSS3 按钮小结
2012/10/03 HTML / CSS
CSS3实现千变万化的文字阴影text-shadow效果设计
2016/04/26 HTML / CSS
法国时尚童装网站:Melijoe
2016/08/10 全球购物
定义一结构体数组表示分数,并求两个分数相加之和
2013/06/11 面试题
土木工程专业自荐信
2013/10/04 职场文书
自荐信格式范文
2013/10/07 职场文书
群众路线教育实践活动整改落实情况汇报
2014/10/28 职场文书
MySQL中utf8mb4排序规则示例
2021/08/02 MySQL