React Native 上传图片到阿里云 OSS (2017年)

2018-5-14 更新

完整代码:
https://github.com/1c7/react-native-upload-to-aliyun-oss


直接上结论

阿里云 Javascript SDK 和 Node SDK 都不能直接拿来用,会碰到各种问题。
阿里云没有 React Native SDK (截止至 2017年12月25号 没有)。

我参照了 阿里云的"客户端签名直传 DEMO"把签名和文件上传搞定了。

问题描述

React Native 的 App 里需要上传图片到阿里云 OSS。
阿里云的 SDK 文档里有很多不同语言的 SDK: https://help.aliyun.com/document_detail/52834.html?spm=5176.doc31947.6.659.79jFT6

  • Javascript-SDK 分浏览器和 Node。
    浏览器这个是肯定没法用的了。

Node 也没法照着文档直接

npm install ali-oss

然后

var co = require('co');
var OSS = require('ali-oss');
var client = new OSS({
  region: '<Your region>',
  accessKeyId: '<Your AccessKeyId>',
  accessKeySecret: '<Your AccessKeySecret>'
});

这样不行,用不了

背景

我不懂 iOS/Android 开发,所以用 React Native

进展

  1. react-native-node
    https://github.com/staltz/react-native-node
    看起来可用,但问题是不支持 iOS,现在只有安卓。我想要一个跨平台的方案。

  2. https://github.com/janeasystems/nodejs-mobile-react-native
    在看。

  3. rn-nodeify
    https://github.com/tradle/rn-nodeify

  4. https://github.com/lesonli/react-native-aliyun-oss

  5. https://github.com/SpadeGod/react-native-aliyun-oss
    这是基于上一个 lesonli/react-native-aliyun-oss 改进的。
    安装后跑 react-native run-android 报错。
    提了个 issue:https://github.com/SpadeGod/react-native-aliyun-oss/issues/9
    在这个问题解决之前只能先 unlink + uninstall 卸载掉。

大致解决了

先随便给个代码,具体讲解之后再写

import RNFetchBlob from 'react-native-fetch-blob'
import crypto from './crypto'
import hmac from './hmac'
import sha1 from './sha1'
import Base64 from './base64'
// XMLHttpRequest = GLOBAL.originalXMLHttpRequest ?
  // GLOBAL.originalXMLHttpRequest : GLOBAL.XMLHttpRequest;

export default function upload(file) { console.log(‘upload() get paramter’); console.log(file); // file object from react-native-image-picker // example:(image took in android emulator) /* { data: xxxx fileName:"image-a8d8546f-7283-4ea1-bc30-6a0dc1eeb478.jpg" fileSize:8128 height:480 isVertical:true originalRotation:0 path:"/storage/emulated/0/Pictures/image-a8d8546f-7283-4ea1-bc30-6a0dc1eeb478.jpg" type:"image/jpeg" uri:"content://com.bigjpg.provider/app_images/Pictures/image-a8d8546f-7283-4ea1-bc30-6a0dc1eeb478.jpg" width:480 } */

// 修改这里!!! accessid = ‘aaa’; accesskey = ‘bbb’;

// 计算必要的签名和其他参数等 var policyText = { "expiration": "2020-01-01T12:00:00.000Z", //设置该Policy的失效时间,超过这个失效时间之后,就没有办法通过这个policy上传文件了 "conditions": [ ["content-length-range", 0, 1048576000] // 设置上传文件的大小限制 ] };

var policyBase64 = Base64.encode(JSON.stringify(policyText)) var message = policyBase64 var bytes = Crypto.HMAC(Crypto.SHA1, message, accesskey, { asBytes: true }); var signature = Crypto.util.bytesToBase64(bytes);

// 发送请求 var url = ‘https://haha-nice.oss-cn-shenzhen.aliyuncs.com’; // var url = ‘http://bigjpg-upload.oss-cn-shenzhen.aliyuncs.com’; RNFetchBlob.fetch(‘POST’, url, {}, [ { name: ‘key’, data: file.fileName }, { name: ‘policy’, data: policyBase64 }, { name: ‘OSSAccessKeyId’, data: accessid }, { name: ‘success_action_status’, data: ‘200’ }, { name: ‘signature’, data: signature }, { name: ‘file’, filename: file.fileName, type: file.type, data: file.data } ]).then((resp) => { console.log(resp); console.log(resp); }).catch((err) => { console.log(err); }) }

注:有问题可联系 [email protected]

使用 Hugo 构建
主题 StackJimmy 设计