React-Native开发鸿蒙NEXT-图片上传
.markdown-body h1, .markdown-body h2, .markdown-body h3, .markdown-body h4, .markdown-body h5, .markdown-body h6 { line-height: 1.5; margin-top: 35px; margin-bottom: 10px; padding-bottom: 5px }
.markdown-body h1 { font-size: 24px; line-height: 38px; margin-bottom: 5px }
.markdown-body h2 { font-size: 22px; line-height: 34px; padding-bottom: 12px; border-bottom: 1px solid rgba(236, 236, 236, 1) }
.markdown-body h3 { font-size: 20px; line-height: 28px }
.markdown-body h4 { font-size: 18px; line-height: 26px }
.markdown-body h5 { font-size: 17px; line-height: 24px }
.markdown-body h6 { font-size: 16px; line-height: 24px }
.markdown-body p { line-height: inherit; margin-top: 22px; margin-bottom: 22px }
.markdown-body img { max-width: 100% }
.markdown-body hr { border-top: 1px solid rgba(221, 221, 221, 1); border-right: none; border-bottom: none; border-left: none; margin-top: 32px; margin-bottom: 32px }
.markdown-body code { border-radius: 2px; overflow-x: auto; background-color: rgba(255, 245, 245, 1); color: rgba(255, 80, 44, 1); font-size: 0.87em; padding: 0.065em 0.4em }
.markdown-body code, .markdown-body pre { font-family: Menlo, Monaco, Consolas, Courier New, monospace }
.markdown-body pre { overflow: auto; position: relative; line-height: 1.75 }
.markdown-body pre>code { font-size: 12px; padding: 15px 12px; margin: 0; word-break: normal; display: block; overflow-x: auto; color: rgba(51, 51, 51, 1); background: rgba(248, 248, 248, 1) }
.markdown-body a { text-decoration: none; color: rgba(2, 105, 200, 1); border-bottom: 1px solid rgba(209, 233, 255, 1) }
.markdown-body a:active, .markdown-body a:hover { color: rgba(39, 91, 140, 1) }
.markdown-body table { display: inline-block !important; font-size: 12px; width: auto; max-width: 100%; overflow: auto; border: 1px solid rgba(246, 246, 246, 1) }
.markdown-body thead { background: rgba(246, 246, 246, 1); color: rgba(0, 0, 0, 1); text-align: left }
.markdown-body tr:nth-child(2n) { background-color: rgba(252, 252, 252, 1) }
.markdown-body td, .markdown-body th { padding: 12px 7px; line-height: 24px }
.markdown-body td { min-width: 120px }
.markdown-body blockquote { color: rgba(102, 102, 102, 1); padding: 1px 23px; margin: 22px 0; border-left: 4px solid rgba(203, 203, 203, 1); background-color: rgba(248, 248, 248, 1) }
.markdown-body blockquote:after { display: block; content: "" }
.markdown-body blockquote>p { margin: 10px 0 }
.markdown-body ol, .markdown-body ul { padding-left: 28px }
.markdown-body ol li, .markdown-body ul li { margin-bottom: 0; list-style: inherit }
.markdown-body ol li .task-list-item, .markdown-body ul li .task-list-item { list-style: none }
.markdown-body ol li .task-list-item ol, .markdown-body ol li .task-list-item ul, .markdown-body ul li .task-list-item ol, .markdown-body ul li .task-list-item ul { margin-top: 0 }
.markdown-body ol ol, .markdown-body ol ul, .markdown-body ul ol, .markdown-body ul ul { margin-top: 3px }
.markdown-body ol li { padding-left: 6px }
.markdown-body .contains-task-list { padding-left: 0 }
.markdown-body .task-list-item { list-style: none }
@media (max-width: 720px) { .markdown-body h1 { font-size: 24px } .markdown-body h2 { font-size: 20px } .markdown-body h3 { font-size: 18px } }.markdown-body pre, .markdown-body pre>code.hljs { color: rgba(51, 51, 51, 1); background: rgba(248, 248, 248, 1) }
.hljs-comment, .hljs-quote { color: rgba(153, 153, 136, 1); font-style: italic }
.hljs-keyword, .hljs-selector-tag, .hljs-subst { color: rgba(51, 51, 51, 1); font-weight: 700 }
.hljs-literal, .hljs-number, .hljs-tag .hljs-attr, .hljs-template-variable, .hljs-variable { color: rgba(0, 128, 128, 1) }
.hljs-doctag, .hljs-string { color: rgba(221, 17, 68, 1) }
.hljs-section, .hljs-selector-id, .hljs-title { color: rgba(153, 0, 0, 1); font-weight: 700 }
.hljs-subst { font-weight: 400 }
.hljs-class .hljs-title, .hljs-type { color: rgba(68, 85, 136, 1); font-weight: 700 }
.hljs-attribute, .hljs-name, .hljs-tag { color: rgba(0, 0, 128, 1); font-weight: 400 }
.hljs-link, .hljs-regexp { color: rgba(0, 153, 38, 1) }
.hljs-bullet, .hljs-symbol { color: rgba(153, 0, 115, 1) }
.hljs-built_in, .hljs-builtin-name { color: rgba(0, 134, 179, 1) }
.hljs-meta { color: rgba(153, 153, 153, 1); font-weight: 700 }
.hljs-deletion { background: rgba(255, 221, 221, 1) }
.hljs-addition { background: rgba(221, 255, 221, 1) }
.hljs-emphasis { font-style: italic }
.hljs-strong { font-weight: 700 }
React-Native开发鸿蒙NEXT-图片上传
原创 悬空八只脚 悬空八只脚 2024年10月30日 10:11 江苏
之前在React-Native开发鸿蒙NEXT(5)
React-Native开发鸿蒙NEXT(5)
悬空八只脚,公众号:悬空八只脚React-Native开发鸿蒙NEXT(5)
里提到了鸿蒙下OSS上传的问题当时没有解决,后来解决了把这事忘记交代了,这里补充一下。后续关于React-Native开发鸿蒙NEXT一些技术输出不再以编号命名,基本会以技术点为标题便于查找,尽量多聊些干货
由于阿里云OSS没有HarmonyOS NEXT版本的SDK,只能使用web直传方式来实现RN端的图片上传,事实上阿里云对于HarmonyOS NEXT的最佳实践也是基于web直传来实现的。
(网址:
HarmonyOS NEXT的最佳实践help.aliyun.com/zh/oss/use-…
这里结合下实际项目来整体说明下图片上传流程。
图片的选取项目中使用的是react-native-image-picker
(网址:
react-native-image-pickerhttps://gitee.com/react-native-oh-library/usage-docs/blob/master/zh-cn/react-native-image-picker.md
实测发现如果相片高宽大于2000会出现报错的问题,最好限制一下尺寸
import {
launchImageLibrary,
launchCamera,
ImageLibraryOptions,
CameraOptions,
} from 'react-native-image-picker';
......
// 测试最高宽高2000就会报500错误,这里用1500
launchImageLibrary(
{
mediaType: 'photo',
maxWidth: 1500,
maxHeight: 1500,
quality: 1,
selectionLimit: 1,
},
.......
通过相机或者相片库返回的数据格式如下:
{
"assets": [{
"fileName": "screenshot_20240807_122206.jpg",
"type": "jpg",
"fileSize": 1467676,
"originalPath": "file://media/Photo/1/IMG_1723004626_000/screenshot_20240807_122206.jpg",
"height": 200,
"width": 200,
"uri": "/data/storage/el2/base/haps/entry/cache/rn_image_picker_lib_temp_a5421e0c-f687-4f76-9567-13147cc1a9bf.jpg"
}]
}
上传必须用到的字段是fileName和uri。项目中图片的上传是基于调用后台接口做的Form表单提交,这里列举下Form的结构,去除了项目相关的业务内容
import FS from 'react-native-fs';
//上传
export async function upload(uri: string, fileName: string) {
try {
const filecontent = await FS.readFile(uri, 'base64');
// convertBase64UrlToBlob(filecontent);
const body = new FormData();
// File64是后台业务定义的文件内容接收字段
body.append('File64', filecontent);
body.append('FileName', fileName);
const options = {
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data',
},
body,
};
const resp = await fetch(省略请求接口, options);
const text = await resp.text();
const json = JSON.parse(text);
// 如果请求失败
...省略业务异常
return json;
} catch (e) {
...省略异常处理
}
}
其中利用react-native-fs来根据uri获取文件内容。
(网址:
react-native-fshttps://gitee.com/react-native-oh-library/usage-docs/blob/master/zh-cn/react-native-fs.md
convertBase64UrlToBlob方法用来将获取到的base64格式文件内容转化为Blob,具体是否需要得看后台小伙伴的定义。网上查找到的资料转化后结果与基于在线转化的结果不一致,可以直接使用下面的方法。
function convertBase64UrlToBlob(base64: string) {
try {
let type = base64.split(',')[0].match(/:(.*?);/)[1];//提取base64头的type如 'image/png'
let bytes = atob(base64.split(',')[1]);//去掉url的头,并转换为byte (atob:编码 btoa:解码)
//处理异常,将ascii码小于0的转换为大于0
//let ab = new ArrayBuffer(bytes.length);//通用的、固定长度(bytes.length)的原始二进制数据缓冲区对象
let ia = new Uint8Array(bytes.length);
for (let i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i);
}
let blob = new Blob([ia], {type: type});
// console.log(blob);
return blob;
} catch (e) {
...省略异常处理
}
}
建议将上传做成接口请求形式,避免暴露oss的accessKey和secret。
更多内容可关注
我的公众号悬空八只脚
React-Native开发鸿蒙NEXT-图片上传的更多相关文章
- 详细阐述Web开发中的图片上传问题
Web开发中,图片上传是一种极其常见的功能.但是呢,每次做上传,都花费了不少时间. 一个"小功能"花费我这么多时间,真心不愉快. So,要得认真分析下原因. 1.在最初学习Java ...
- react native中如何往服务器上传网络图片
let common_url = 'http://192.168.1.1:8080/'; //服务器地址 let token = ''; //用户登陆后返回的token /** * 使用fetch实现 ...
- 微信小程序开发之多图片上传+服务端接收
前言: 业务需求,这次需要做一个小程序同时选中三张图片一起上传到服务端,后端使用的.NET WEBAPI接收数据保存. 使用技术: 在这章中将会使用到微信小程序wx.uploadFile(Object ...
- React后台管理手动封装图片上传组件
分为两个文件夹,index.js(逻辑文件) styled.js(样式文件) index.js文件,编写完成之后在对应的地方引入即可 import React from "react&quo ...
- HTML5开发笔记:图片上传预览
我们知道通过<input type="file">可以用来进行一个图片或者文件的上传,然而浏览器自带的一个缩略图预览的功能其实是相当不美观的,很多时候我们希望可以在上传 ...
- yii2-basic后台管理功能开发之四:图片上传FileInput
我采用的是 kartik-v/yii2-widget-fileinput的文件上传插件,大家可以去github查看详细的安装方法和使用说明. 需求:上传图片+可以预览缩略图 在这里说说我碰到的问题:限 ...
- (转)React Native 使用react-native-image-picker库实现图片上传功能
react-native-image-picker作为一个集成相机和相册的功能的第三方库,因为其使用相对简单受到前端开发人员的喜爱. react-native-image-picker使用 首先,安装 ...
- 基于Node的React图片上传组件实现
写在前面 红旗不倒,誓把JavaScript进行到底!今天介绍我的开源项目 Royal 里的图片上传组件的前后端实现原理(React + Node),花了一些时间,希望对你有所帮助. 前端实现 遵循R ...
- iOS 开发之路(WKWebView内嵌HTML5之图片上传) 五
HTML5页面的图片上传功能在iOS端的实现. 首先,页面上用的是plupload组件,在wkwebview上存在两个坑需要修复才能正常使用. 问题:在webview上点击选择照片/相机拍摄,就会出现 ...
- vuejs开发组件分享之H5图片上传、压缩及拍照旋转的问题处理
一.前言 三年.net开发转前端已经四个月了,前端主要用webpack+vue,由于后端转过来的,前端不够系统,希望分享下开发心得与园友一起学习. 图片的上传之前都是用的插件(ajaxupload), ...
随机推荐
- luogu-P3343题解
简要题意 给定一张 \(n\) 个点 \(m\) 条边的图,边的边权是 \([0, 1]\) 之间均匀分布的随机实数,且相互独立.求最小生成树的最大边权的期望值. 思路 首先有一个比较神秘的跟概率有关 ...
- 【论文随笔】多行为序列Transformer推荐(Multi-Behavior Sequential Transformer Recommender)
前言 今天读的论文为一篇于2022年7月发表在第45届国际计算机学会信息检索会议(SIGIR '22)的论文,文章主要为推荐系统领域提供了一个新的视角,特别是在处理用户多行为序列数据方面,提出了一种有 ...
- 前端解析excel表格实现
1. 背景:在做react项目时,遇到一个解析excel的需求变更,把从原来后端解析变更为前端解析. 1.1 由于后端解析excel文件有安全隐患,因为项目中后端不允许上传文件,当然后端解析对前端来说 ...
- Golang 入门 : 整型
整型介绍 Go语言同时提供了有符号和无符号类型的整数运算.这里有 int8.int16.int32 和 int64 四种截然不同大小的有符号整形数类型,分别对应 8.16.32.64 bit大小的有符 ...
- Golang 入门 : Go语言介绍
简介 Go 语言又称 Golang,由 Google 公司于 2009 年发布,近几年伴随着云计算.微服务.分布式的发展而迅速崛起,跻身主流编程语言之列,和 Java 类似,它是一门静态的.强类型的. ...
- 2025年3月GESP八级真题解析
第一题--上学 题目描述 C 城可以视为由 \(n\) 个结点与 \(m\) 条边组成的无向图.这些结点依次以 \(1,2,-,n\) 标号,边依次以 \(1,2,-,m\) 标号.第 \(i\) 条 ...
- Wyn商业智能V8.0 Update1版本发布
智启未来,Wyn商业智能V8.0 Update1版本深度融合AI技术.工业物联网与数据工程能力,带来三大核心亮点及100+新特性,致力于为企业打造全场景智能分析平台,助力构建从数据加工到智能决策的全链 ...
- 支持VS2022的包发布工具NuPack 2022发布
我们很高兴地宣布 NuPack 2022 正式发布!这是一个开源项目,旨在简化 .NET 开发中的 NuGet 包发布流程. NuPack 是什么? NuPack 是一个轻量级工具,VS扩展,它可以帮 ...
- 【Python】文件批量重命名
需求: 经常有很多相似的文件需要重命名,如果一个一个来太麻烦了,正好会Python,所以用Python写了个脚本,把符合要求的文件的文件名修改为新的. 代码: # coding:utf-8 # @Ti ...
- Netty源码—10.Netty工具之时间轮
大纲 1.什么是时间轮 2.HashedWheelTimer是什么 3.HashedWheelTimer的使用 4.HashedWheelTimer的运行流程 5.HashedWheelTimer的核 ...