React-native文件上传
2018-08-29 16:24
866 查看
上一篇说了文件选择的使用,
/detail/2746528040.html
选了文件就要上传,这篇就记录一下文件上传
这是antd的一个UI库,不知道的同学自行去学习,选择图片和拍照有时间在补上,他们的上传方法是同一个,还包含了一点点RN和webview的交互以及组件封装调用
https://rn.mobile.ant.design/components/toast-cn/
1、调用各自文件选择方式
延迟调用文件选择是为了用户体验,以及权限获取延时问题
2、上传前的一些处理
我们不能让用户传一些乱七八糟的东西上去,所以要对文件进行筛选,我们就简陋的用文件后缀名筛选一下就行了
4、调用上传文件的方法
this.props.sendWebMessage(fileList)这是上传成功后和WebView交互,有时间会记一下RN和WebView的交互
5、这是上传方法
其中必须的的参数,参数名不能改,如果上传的文件是中文名,还要对name字段编码(后台接收需要解码,才能得到真正的文件名),不然会报类似的错误
unexpected char 0*6587 at 34 in content-disposition
引用组件的代码片段
组件代码
上传组件代码
/detail/2746528040.html
选了文件就要上传,这篇就记录一下文件上传
这是antd的一个UI库,不知道的同学自行去学习,选择图片和拍照有时间在补上,他们的上传方法是同一个,还包含了一点点RN和webview的交互以及组件封装调用
https://rn.mobile.ant.design/components/toast-cn/
1、调用各自文件选择方式
延迟调用文件选择是为了用户体验,以及权限获取延时问题
2、上传前的一些处理
我们不能让用户传一些乱七八糟的东西上去,所以要对文件进行筛选,我们就简陋的用文件后缀名筛选一下就行了
4、调用上传文件的方法
this.props.sendWebMessage(fileList)这是上传成功后和WebView交互,有时间会记一下RN和WebView的交互
5、这是上传方法
其中必须的的参数,参数名不能改,如果上传的文件是中文名,还要对name字段编码(后台接收需要解码,才能得到真正的文件名),不然会报类似的错误
unexpected char 0*6587 at 34 in content-disposition
引用组件的代码片段
/** * @Date: 2018-08-08T17:25:36+08:00 * @Email: xiao.hxj@qq.com * @Last modified time: 2018-08-23T08:17:26+08:00 */ import React, { Component } from 'react'; import { StyleSheet, View, Text, WebView, AsyncStorage} from 'react-native'; import { deviceWidth ,isIOS,deviceHeight } from '../../../utils/common'; import { _Download } from '../../../utils/downloadImage'; import { connect } from 'react-redux'; import {ActionSheet, Toast} from "antd-mobile-rn"; import Header from "../../../components/Common/Header"; import Modal from "../../../components/Common/Modal"; import NoDate from "../../../components/Common/NoDate"; import NoMore from "../../../components/Common/NoMore"; import LoadingMore from "../../../components/Common/LoadingMore"; const isIPhone = new RegExp('\\biPhone\\b|\\biPod\\b', 'i').test(window.navigator.userAgent); let wrapProps; if (isIPhone) { wrapProps = { onTouchStart: e => e.preventDefault(), }; } class Outweb extends Component { constructor(props){ super(props); this.state = { visible:false, // url: "http://..../appjump" // url: "http://..../appjump" url: "http://..../appjump" } } async componentDidMount(){ let token = await AsyncStorage.getItem('token') let url = `${this.state.url}?token=${token}` this.setState({url:url.replace(/"/g,'')}) console.log(url.replace(/"/g,'')); } // 开始加载 onLoadStart(e){ Toast.loading('加载中...', 0) } // 加载成功 onLoad (){ Toast.hide() } // 加载失败 onError(e){ Toast.hide() this.props.navigation.goBack() Toast.info('应用加载失败,请稍后重试',2) } // 上传组件 getMessage onMessage(e){ const message = e.nativeEvent.data if(message === 'upload'){ Toast.loading('加载中...',0) this.setState({visible:true}) }else { // console.log('*************',message); _Download(message); } } // 回调 sendWebMessage(fileList){ this.refs.webview.postMessage(fileList); } render(){ return( <View style={styles.page}> <Header title={"外部页面"} goBack={() => {this.props.navigation.goBack();Toast.hide()}}></Header> <WebView ref={'webview'} onLoadStart = {this.onLoadStart.bind(this)} onLoad = {this.onLoad.bind(this)} onError = {this.onError .bind(this)} onMessage = {this.onMessage.bind(this)} automaticallyAdjustContentInsets={false} startInLoadingState scalesPageToFit = {true} javaScriptEnabled = {true} domStorageEnabled = {true} style={styles.webView} source={{uri: this.state.url,method: 'GET'}} /> <Modal sendWebMessage={this.sendWebMessage.bind(this)} visible={this.state.visible} /> </View> ) } } const styles = StyleSheet.create({ page:{ flex:1, backgroundColor:"#fff", }, webView: { height: isIOS ? (deviceHeight-44):(deviceHeight-64), width: deviceWidth }, }) export default connect(({cstmrModel, loading}) => ({ cstmrModel, loading:loading.models.cstmrModel }))(Outweb)
组件代码
/** * @Date: 2018-08-21T15:52:02+08:00 * @Email: xiao.hxj@qq.com * @Last modified time: 2018-08-23T09:51:26+08:00 */ import React from "react"; import { connect } from 'react-redux' import { View, Text, StyleSheet, Image, TouchableOpacity } from "react-native"; import { activeOpacity ,acceptFile } from "../../utils/common"; import { ActionSheet, Toast, Modal} from "antd-mobile-rn"; import ImagePicker from 'react-native-image-crop-picker'; import RNFileSelector from 'react-native-file-selector'; import { FileUpload } from '../../utils/FileUpload' import RNFS from 'react-native-fs' const isIPhone = new RegExp('\\biPhone\\b|\\biPod\\b', 'i').test(window.navigator.userAgent); let wrapProps; if (isIPhone) { wrapProps = { onTouchStart: e => e.preventDefault(), }; } class UploadModal extends React.PureComponent { constructor(props) { super(props); this.state={ visible:false } } componentWillUnmount(){ ImagePicker.clean().then(() => { console.log('clean file cache'); }).catch(e => { console.log(e); }); } async fileUpload(fileAry) { Toast.loading('上传中...',0) try { const res = await FileUpload(fileAry) if (res.success) { let fileList = JSON.stringify(res.attList) this.props.sendWebMessage(fileList) Toast.hide() }else { Toast.hide() Toast.info(res.message,2) } } catch (e) { Toast.hide() // console.log(e); } } // file上传 upLoadFile(){ let that = this; Toast.hide() RNFileSelector.Show( { title: '选择文件', closeMenu: true, onDone: (path) => { let params = [{ mime:'', path:`file://${path}` }] let fileArr = path.split('.'); if (fileArr.length > 1 && acceptFile.indexOf(fileArr[fileArr.length-1]) !==-1) { params.mime = `.${fileArr[fileArr.length-1]}` // console.log('params*****',params); that.fileUpload(params) }else { Toast.info('文件类型错误,请重新选择!',2); } }, onCancel: () => { console.log('cancelled') } }) } // image上传 upLoadImage(params){ let that = this; Toast.hide() if (params==='camera') { ImagePicker.openCamera({ width: 300, height: 400, multiple: true, hideBottomControls:true, }).then(image => { this.fileUpload(image) }).catch((e)=>{ Toast.info('未选择文件或文件异常!',2) }); }else { ImagePicker.openPicker({ mediaType:'photo', multiple: true }).then(images => { that.fileUpload(images) }).catch((e)=>{ Toast.info('未选择文件或文件异常!',2) }); } } showActionSheet(){ Toast.hide(); let that = this; const BUTTONS = [ '拍摄', '选择图片', '选择文件', '取消', ]; ActionSheet.showActionSheetWithOptions( { maskClosable:false, options: BUTTONS, cancelButtonIndex: 3, }, (buttonIndex: any) => { if (BUTTONS[buttonIndex]==='拍摄') { Toast.loading('加载中...',0) this.timer = setTimeout(()=>{that.upLoadImage('camera')},200) }else if (BUTTONS[buttonIndex]==='选择图片') { Toast.loading('加载中...',0) that.timer = setTimeout(()=>{that.upLoadImage()},200) } else if (BUTTONS[buttonIndex]==='选择文件') { Toast.loading('加载中...',0) that.timer = setTimeout(()=>{that.upLoadFile()},200) } }, ); } render() { const { visible } = this.props return ( <View> { visible ? this.showActionSheet():null } </View> ); } } const styles = StyleSheet.create({ content:{ flexDirection:'row', justifyContent:'space-around', alignItems:'center' }, img:{ height:60, width:60, } }); export default connect(({ M_My }) => ({ M_My }))(UploadModal);
上传组件代码
import { AsyncStorage } from 'react-native'; import RequestUrl from "../services/RequestUrl"; import { Storage } from "../utils"; const baseUrl = async () => { ...... } export const FileUpload = async(fileAry) => { let formData = new FormData(); let token = await AsyncStorage.getItem('token'); let serverUrl = await baseUrl(); if (!fileAry.length) return {success:false,message:'未选择文件'}; //因为需要上传多个文件,所以需要遍历数组,把文件的路径数组放入formData中 for( let i = 0; i < fileAry.length; i++ ){ let path = fileAry[i].path; let arr = path.split('/');//截取获取文件名 // 文件的类型,以及中文文件名编码 let file = { uri: path, type: 'multipart/form-data', name: escape(arr[arr.length-1]), fileType: fileAry[i].mime }; //这里的key(uri和type和name)不能改变, formData.append("file", file); //这里的files就是后台需要的key //这里的files就是后台需要的key } // console.log(formData); let response = await fetch(`${serverUrl}${RequestUrl.FILE_UPLOAD}`,{ method:'POST', headers:{ // 'Accept': 'Application/json', 'Content-Type':'multipart/form-data', 'token': token, 'moduelType':8 }, body:formData, }) // console.log('response',await response.json()); return await response.json(); }
相关文章推荐
- React Native fench FormData 上传文件
- react native 之上传文件
- 解决 react native 的 webview 组件不支持android客户端上传图片文件问题
- React Native文件上传下载
- RN文件上传(仅ios),下载,创建,删除等文件操作(兼容IOS和Android)--react-native-fs
- react-native-qiniu源码修改(实现文件上传,上传策略等)
- 【服务端知识点】(十五天)文件上传实现——30天node+mongo+react+redux+express搭建完美资源后台管理系统+前端(全栈工程师 结合antd)
- react-native 实现上传功能
- 【linux】【最大文件打开数】【react native】
- React文件及头像上传
- ReactNative之bundle文件瘦身(google-diff-match-patch)
- React-Native系列Android——Javascript文件加载过程分析
- React 使用fromidable 模块进行文件上传出现First argument must be a string 的解析错误的原因
- React Native 之读取JSON 文件
- React Native之APK文件签名及打包
- react+antd+feathers实现前后端简单的文件上传下载
- 如何创建一个依赖Android AAR文件的React Native组件
- RN-第三方-react-native-image-picker,选择图片上传
- WebUploader文件上传(react),带参数
- React Native下载打开pdf文件