服务端:
const uploadSignatureUrl = ({ name, mimeType }) => {
return client.signatureUrl(name, {
// 设置过期时间为300秒。
expires: 300,
// 设置请求方式为PUT。
method: 'PUT',
// 设置PUT请求的Content-Type
"Content-Type": mimeType,
});
}
App
export const requestBlob = async (uri) => {
return await new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = function () {
resolve(xhr.response); // when BlobModule finishes reading, resolve with the blob
};
xhr.onerror = function () {
reject(new TypeError('Network request failed')); // error occurred, rejecting
};
xhr.responseType = 'blob'; // use BlobModule's UriHandler
xhr.open('GET', uri, true); // fetch the blob from uri in async mode
xhr.send(null); // no initial data
});
};
let blob = await requestBlob(uri);
let res = await fetch(url, {
method: 'PUT',
body: blob,
headers: { 'content-type': mimeType },
});
blob.close();
return res;
注意问题:
- 签名name,带上文件夹路径,eg:
/image/xxx.jpg
- 签名带Content-Type和PUT请求Content-Type要一致
遇到问题:
- 安卓上传文件时,fetch请求一直返回
# TypeError: Network request failed
错误信息太少,所以第一步需要解决怎去调试fetch请求,先了解fetch在Android上的实现, 大概是这样的
fetch --(whatwg-fetch)--> XMLHttpRequest -> RCTNetworking --(android)--> NetworkingModule.sendRequest
具体可以参考 github.com/expo/expo/i…
我是先在whatwg-fetch下的断点,但是看不出来问题,最后在NetworkingModule的sendRequest下断点跟踪才发现了文件路径不存在的问题,然后问题就好解决了。