.markdown-body { line-height: 1.75; font-weight: 400; font-size: 16px; overflow-x: hidden; color: rgba(37, 41, 51, 1) }
.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直传来实现的。

(网址:

help.aliyun.com/zh/oss/use-…)

HarmonyOS NEXT的最佳实践help.aliyun.com/zh/oss/use-…

这里结合下实际项目来整体说明下图片上传流程。

图片的选取项目中使用的是react-native-image-picker

(网址:

gitee.com/react-nativ…)

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获取文件内容。

(网址:

gitee.com/react-nativ…)

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-图片上传的更多相关文章

  1. 详细阐述Web开发中的图片上传问题

    Web开发中,图片上传是一种极其常见的功能.但是呢,每次做上传,都花费了不少时间. 一个"小功能"花费我这么多时间,真心不愉快. So,要得认真分析下原因. 1.在最初学习Java ...

  2. react native中如何往服务器上传网络图片

    let common_url = 'http://192.168.1.1:8080/'; //服务器地址 let token = ''; //用户登陆后返回的token /** * 使用fetch实现 ...

  3. 微信小程序开发之多图片上传+服务端接收

    前言: 业务需求,这次需要做一个小程序同时选中三张图片一起上传到服务端,后端使用的.NET WEBAPI接收数据保存. 使用技术: 在这章中将会使用到微信小程序wx.uploadFile(Object ...

  4. React后台管理手动封装图片上传组件

    分为两个文件夹,index.js(逻辑文件) styled.js(样式文件) index.js文件,编写完成之后在对应的地方引入即可 import React from "react&quo ...

  5. HTML5开发笔记:图片上传预览

    我们知道通过<input type="file">可以用来进行一个图片或者文件的上传,然而浏览器自带的一个缩略图预览的功能其实是相当不美观的,很多时候我们希望可以在上传 ...

  6. yii2-basic后台管理功能开发之四:图片上传FileInput

    我采用的是 kartik-v/yii2-widget-fileinput的文件上传插件,大家可以去github查看详细的安装方法和使用说明. 需求:上传图片+可以预览缩略图 在这里说说我碰到的问题:限 ...

  7. (转)React Native 使用react-native-image-picker库实现图片上传功能

    react-native-image-picker作为一个集成相机和相册的功能的第三方库,因为其使用相对简单受到前端开发人员的喜爱. react-native-image-picker使用 首先,安装 ...

  8. 基于Node的React图片上传组件实现

    写在前面 红旗不倒,誓把JavaScript进行到底!今天介绍我的开源项目 Royal 里的图片上传组件的前后端实现原理(React + Node),花了一些时间,希望对你有所帮助. 前端实现 遵循R ...

  9. iOS 开发之路(WKWebView内嵌HTML5之图片上传) 五

    HTML5页面的图片上传功能在iOS端的实现. 首先,页面上用的是plupload组件,在wkwebview上存在两个坑需要修复才能正常使用. 问题:在webview上点击选择照片/相机拍摄,就会出现 ...

  10. vuejs开发组件分享之H5图片上传、压缩及拍照旋转的问题处理

    一.前言 三年.net开发转前端已经四个月了,前端主要用webpack+vue,由于后端转过来的,前端不够系统,希望分享下开发心得与园友一起学习. 图片的上传之前都是用的插件(ajaxupload), ...

随机推荐

  1. [tldr] 使用ip.sb检查自己所在局域网的公网IP

    使用ip a等一些命令行工具可以帮助我们检查自己的内网IP,但是,如何获取自己的在公网下的IP(即当前所在的局域网被分配的公网IP) 如果使用爬虫,这个IP也是很重要的.BAN IP就是这个IP ht ...

  2. 前端解析excel表格实现

    1. 背景:在做react项目时,遇到一个解析excel的需求变更,把从原来后端解析变更为前端解析. 1.1 由于后端解析excel文件有安全隐患,因为项目中后端不允许上传文件,当然后端解析对前端来说 ...

  3. 单词搜索 & 周赛第二道

    单词搜索 描述: 给定一个二维网格和一个单词,找出该单词是否存在于网格中.单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中"相邻"单元格是那些水平相邻或垂直相邻的单元格.同 ...

  4. 魔方求解器程序(层先法,java版本)

    实现了一个三阶魔方的层先法求解程序:https://github.com/davelet/java-puzzle-resolver 欢迎试用. 用法 1. 随机试用 不关注起始状态的话可以用程序的随机 ...

  5. AntennaMagus中文培训教程

    AntennaMagus中文培训教程 链接:https://pan.baidu.com/s/1Svc613HvfUtIMB3uOXILkg 提取码:0s2c

  6. Proxmox ve(Pve) 安装windows server

    1.安装proxmox ve点击直达 官网地址 下载下来如果下载速度太慢 可以去安装个IDM https://www.52pojie.cn/thread-1013874-1-1.html 然后需要制作 ...

  7. DeepSeek引发的AI发展路径思考

    DeepSeek引发的AI发展路径思考 参考文章来源于科技导报 ,作者李国杰院士 | 哈工大 DeepSeek 技术前沿与应用讲座 1. DeepSeek 的科技突破 7 天之内 DeepSeek 的 ...

  8. 【Linux】5.6 Shell打印输出指令

    Shell打印输出命令 1. echo命令 Shell 的 echo 指令与 PHP 的 echo 指令类似,都是用于字符串的输出.命令格式:echo string 您可以使用echo实现更复杂的输出 ...

  9. Docker Commonds

    脑子不够用,记录下自己所学所用的命令,备忘...不断补充. 最最基本的命令 查看 docker 信息 docker info 查看 docker 版本及相关信息 docker version 仅查看 ...

  10. 《机器人SLAM导航核心技术与实战》第1季:第5章_机器人主机

    <机器人SLAM导航核心技术与实战>第1季:第5章_机器人主机 视频讲解 [第1季]5.第5章_机器人主机-视频讲解 [第1季]5.1.第5章_机器人主机_X86与ARM主机对比-视频讲解 ...