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

  • Android-SDK 我要是会写 Android 的话这个可能看得懂怎么和 React Native 整合。但我不会安卓(学过一丢丢基础,不够用)。学习成本太高,费时,弃用。

  • 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);
    })
}

注:有问题可联系 guokrfans@gmail.com

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

Subscribe to 1c7 的博客