React Native 上传图片至七牛云存储

3,094 阅读3分钟

长话短说,小编这几个小时被这个毕业设计的需求弄得整个人很蒙蔽!我想实现在app上上传文件并将文件存储到七牛云平台上面,由于对前端的promise,fetch等知识了解不深入,再加上不熟悉七牛云存储文档,最为坑的是网上还没有线程的示例代码!唯一的官网上的react native SDK又没有维护,听说写这个SDK的作者早就辞职了!很忧伤啊!小编不就是赶个毕业设计!好了,下面我讲下流程代码给大家以及遇到的一些坑!

一、react native端上传代码

首先实现的页面就这个样子,先放一张大头贴(样式有点丑,后期再调)

在这个页面中用到了一些第三方组件,所以你必须先导入组件:

yarn add react-native-image-picker : 该库用于从相机选择图片

yarn add react-native-qiniu: 七牛云上传组件

核心上传代码如下:

/**
 * 直传文件
 */
方法签名为:`function uploadFile(uri, token, formInput, onprogress)`
使用如下:
upload(uri) {//传入一个图片选择地址
          qiniu.Rpc.uploadFile(uri,'_5q1hS4hLzHrWvNfK5wnQczIPub43_NnvMl7d-4B:RD93EuPYVULGU7AAmBMVp0T8oxs=:eyJzY29wZSI6Im15YXBwIiwiZGVhZGxpbmUiOjE1OTh9', {
                key:'asdf',
                type:'application/octet-stream',
                name:undefined,
              }
            ,function (resp) {
            console.log(resp);
          });
     }
  • token:上传令牌,通过七牛官网java sdk生成
  • formInput:formInput对象如何配置请参考七牛官方文档“直传文件”一节

key:表示你资源上传到七牛云之后保存的文件名

type:表示uri所代表的类型,此处为二进制流,上传文件一般都是二进制

name:未知,随便什么

二、上图页面代码(由于小编毕设代码未开源,故页面某些部分如header可能提示找不到

/**
	发表评论
*/
import React, { Component } from 'react';
import Header from '../../components/common/Header';//提示找不到
import {TextareaItem,ImagePicker,InputItem,List,WhiteSpace} from 'antd-mobile';//需要自己安装该库
import Util from '../../utils/Util';//提示找不到
import * as picker  from "react-native-image-picker";
import {
  StyleSheet,
  Text,
  View,
  TextInput,
  TouchableOpacity
} from 'react-native';
var qiniu = require('react-native-qiniu');
var data = [];
const photoOptions = {
    title:'请选择图片',//标题
    cancelButtonTitle:'取消',//取消按钮名称
    takePhotoButtonTitle:'拍照',//相机按钮名称
    chooseFromLibraryButtonTitle:'选择相册...',//从相册取照片名称
	  quality: 0.8,//照片质量
    mediaType:'photo',//可以是照片,也可以是video
    videoQuality:'high',//视频质量
    durationLimit:10,//video最长10s
    allowsEditing: true,//照片是否可以被修改,Ios有效
    noData: false,
    storageOptions: {
        skipBackup: true,
        path: 'images'
    }
};

export default class PicturePost extends Component{

 	constructor(props){
 		super(props);
 		this.state = {
		    files: data
		  }
 	}

  onChange = (files, type, index) => {
    console.log(files, type, index);
    this.setState({
      files,
    });
    console.log("heoolo onChange");
  }

choosePicker=()=>{
        picker.showImagePicker(photoOptions, (response) => {
            console.log('Response = ', response);
            if (response.didCancel) {
                console.log('User cancelled image picker');
            }
            else if (response.error) {
                console.log('ImagePicker Error: ', response.error);
            }else {
                let source = {url: response.uri} ;
				        console.log('source===' + source.url)
                console.log(response)
                var files = this.state.files;
                files.push(source);
               	this.setState({
    			           files:files
    			       });
                console.log('data===' + this.state.files)
            }
        });
    }

     upload(uri) {//这里是核心上传的代码
          qiniu.Rpc.uploadFile(uri,'_5q1hS4hLzHrWvNfK5wnQczIPub43_NnvMl7d-4B:RD93EuPYVULGU7AAmBMVp0T8oxs=:eyJzY29wZSI6Im15YXBwIiwiZGVhZGxpbmUiOjE1MjE4OTAyOTh9', {
                key:'asdf',
                type:'application/octet-stream',
                name:undefined,
              }
            ,function (resp) {
            console.log(resp);
          });
     }

	render(){
		return (
  	         <View style={styles.container}>
      	         	<Header
      						showBack={true}
      						showTitle={true}
      						showSearch={false}
      						sendText='发送'
      						title='书评'
      					/>
    	         	<View style={{width:Util.size.width,backgroundColor:'#fff'}}>
    		         		<TextareaItem
    				            rows={6}
    				            count={200}
    				            placeholder='写点什么吧!'
    				            style={{fontSize:11,backgroundColor:'#fff'}}
    				          />
    	         	</View> 	 
    	         	<ImagePicker
    				          files={files}
    				          selectable={files.length < 2}
    				          onChange={this.onChange}
              				  onImageClick={(index, files) =>{
              				  	console.log(files[index].url)
              				  } }
              				  onAddImageClick={
              				  	this.choosePicker
              				  }
    				    />
                 <List>
                       <InputItem
                          placeholder="请输入书名"
                          labelNumber={7}
                          placeholdertTextColor='#fff'
                        />
                        <InputItem
                          placeholder="请输入作者"
                          labelNumber={7}
                        />
                </List>
                //上传代码在此处触发
                <TouchableOpacity onPress={()=>{
                  let imgAry = this.state.files;
                  console.log(this.state.files)
                        this.upload(imgAry[0].url);
                }}>
                <Text>上传</Text>
                </TouchableOpacity>
	         </View>
         );
	}
}

const styles = StyleSheet.create({
	container:{
		backgroundColor:'#e4e4e4'
	}
});

三、踩过的坑

1、在你导入的react-native-qiniu包的源代码conf.js中,应修改你bucket所在的区域,如小编所在的区域是华南,则填写如下:

2、如果还是不知道formInput怎么配置,那么查看源代码就知道了,如图: