不能直接使用ali-oss 或 uni.upload 的原因
1、为什么不直接使用ali-oss上传呢?
没什么大的原因,只是不能跨端而已。
2、为什么不用uni.upload上传呢?
因为ali-oss Browser.js简单上传是put请求,并且文件直接放在请求的body中。请求如下
附参数:putObject
而uni.uploadFile(OBJECT)是post方法,文件以二进制流的形式放在formData中,
解决方案
把ali-oss 工具类中的请求函数替换成uni-app的。
代码如下
本文章任然使用ali-oss( Browser.js SDK)踩(吐)坑(槽)记录 中我自己写的工具类,修改了init函数,其余代码请移步ali-oss( Browser.js SDK)踩(吐)坑(槽)记录
import OSS, { Buffer } from "ali-oss";
/**
* 这个函数是从 OSS代码中摘抄出来的,具体作用不知道,但是一定要有
* @param {*} buf
* @returns
*/
function toArrayBuffer(buf) {
// If the buffer is backed by a Uint8Array, a faster version will work
if (buf instanceof Uint8Array) {
// If the buffer isn't a subarray, return the underlying ArrayBuffer
if (buf.byteOffset === 0 && buf.byteLength === buf.buffer.byteLength) {
return buf.buffer;
} else if (typeof buf.buffer.slice === "function") {
// Otherwise we need to get a proper copy
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
}
}
if (Buffer.isBuffer(buf)) {
// This is the slow version that will work with any Buffer
// implementation (even in old browsers)
var arrayCopy = new Uint8Array(buf.length);
var len = buf.length;
for (var i = 0; i < len; i++) {
arrayCopy[i] = buf[i];
}
return arrayCopy.buffer;
} else {
throw new Error("Argument must be a Buffer");
}
}
class Client {
// ... 代码略
async init() {
try {
// ... 代码略
this.client = new OSS({
// ... 代码略
});
// 重写request
this.client.urllib.request = async function (url, args, callback) {
if (arguments.length === 2 && typeof args === "function") {
callback = args;
args = {};
}
let { content, method, headers = {} } = args;
// uniapp的请求不允许修改Content-Length
delete headers["Content-Length"];
return new Promise((resolve, reject) => {
uni.request({
url,
data: toArrayBuffer(Buffer.concat([content])),
method,
header: headers,
dataType: "",
responseType: "arraybuffer",
success: res => {
const data = {
data: res.data,
status: res.statusCode,
headers: res.headers,
res: res
};
if (typeof callback === "function") {
callback(data);
}
resolve(data);
},
fail: err => {
reject(err);
}
});
});
};
} catch (e) {
throw new Error("获取oss凭证失败");
}
}
// ... 代码略
}
后记
我后面会把这个工具类在整理一下,上传值github,敬请期待