我如何 POST 或使用本机反应 PUT 原始二进制文件
How can I POST or PUT raw binary using react native
我需要将图像文件从 React Native 应用程序 PUT 到预配置的 s3 上传 URL。我看到一个带有 fetch 的示例,它通过路径将图像作为二进制文件上传,但它是以多部分形式上传的方式进行的。因为 s3 上传 url 只能将其作为主体中的原始二进制文件 - 而不是作为多部分的内容类型,使用 fetch 或任何其他方式将原始二进制图像作为主体的语法是什么React Native 中的库?
以下代码将其作为表单数据上传 - 这不是我想要做的。
var photo = {
uri: response.uri,
name: fileName,
};
const body = new FormData(); // how can I do this not as a form?
body.append('photo', photo);
const results = await fetch('https://somes3uploadurl.com, {
method: 'PUT',
body,
});
事实证明,您可以通过多种方式发送文件,包括 base64
和 Buffer
。
使用react-native-fs and buffer:
以 base64 格式上传成功,但图像不知何故损坏了。所以我使用缓冲区上传:
export const uploadToAws = async (signedRequest, file) => {
const base64 = await fs.readFile(file.uri, 'base64')
const buffer = Buffer.from(base64, 'base64')
return fetch(signedRequest, {
method: 'PUT',
headers: {
'Content-Type': 'image/jpeg; charset=utf-8',
'x-amz-acl': 'public-read',
},
body: buffer,
})
}
请注意,在服务器上,您需要确保设置正确的 Content-Type:{ ContentType: "image/jpeg; charset=utf-8", 'x-amz-acl': 'public-read' }
因为它似乎 fetch 将字符集添加到 Content-Type。
您不需要使用 react-native-fs 或那个缓冲库。相反,只需使用 https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsArrayBuffer 读取文件,将结果传递给 fetch 的 body 参数。 readAsBinaryString 和 readAsDataUrl 给了我奇怪的结果。
注意:我不必将“;charset=utf-8”附加到我的 content-type header.
示例:
const fileReader = new FileReader();
fileReader.addEventListener('load', (event: any) => {
const buffer = event.target.result;
return fetch(link.url, {
method: 'PUT',
body: buffer,
})
.then((response) => {
if (!response.ok) {
throw new Error(
`${response.status}: ${response.statusText}`
);
}
return response;
})
.then(resolve, reject);
});
fileReader.addEventListener('error', reject);
fileReader.addEventListener('abort', reject);
fileReader.readAsArrayBuffer(file);
您也可以使用下一个解决方案:
/**
* @param {{contentType: string, uploadUrl: string}} resourceData for upload your image
* @param {string} file path to file in filesystem
* @returns {boolean} true if data uploaded
*/
async uploadImage(resourceData, file) {
return new Promise((resolver, rejecter) => {
const xhr = new XMLHttpRequest();
xhr.onload = () => {
if (xhr.status < 400) {
resolver(true)
} else {
const error = new Error(xhr.response);
rejecter(error)
}
};
xhr.onerror = (error) => {
rejecter(error)
};
xhr.open('PUT', resourceData.uploadUrl);
xhr.setRequestHeader('Content-Type', resourceData.contentType);
xhr.send({ uri: file });
})
}
然后从您的代码中调用此函数,例如:
let isSuccess = await uploadImage({
contentType: "image/jpeg",
uploadUrl: "http://my.super.web.amazon.service..."
}, "file:///path-to-file-in-filesystem.jpeg")
来源:https://github.com/react-native-community/react-native-image-picker/issues/61#issuecomment-297865475
我需要将图像文件从 React Native 应用程序 PUT 到预配置的 s3 上传 URL。我看到一个带有 fetch 的示例,它通过路径将图像作为二进制文件上传,但它是以多部分形式上传的方式进行的。因为 s3 上传 url 只能将其作为主体中的原始二进制文件 - 而不是作为多部分的内容类型,使用 fetch 或任何其他方式将原始二进制图像作为主体的语法是什么React Native 中的库?
以下代码将其作为表单数据上传 - 这不是我想要做的。
var photo = {
uri: response.uri,
name: fileName,
};
const body = new FormData(); // how can I do this not as a form?
body.append('photo', photo);
const results = await fetch('https://somes3uploadurl.com, {
method: 'PUT',
body,
});
事实证明,您可以通过多种方式发送文件,包括 base64
和 Buffer
。
使用react-native-fs and buffer:
以 base64 格式上传成功,但图像不知何故损坏了。所以我使用缓冲区上传:
export const uploadToAws = async (signedRequest, file) => {
const base64 = await fs.readFile(file.uri, 'base64')
const buffer = Buffer.from(base64, 'base64')
return fetch(signedRequest, {
method: 'PUT',
headers: {
'Content-Type': 'image/jpeg; charset=utf-8',
'x-amz-acl': 'public-read',
},
body: buffer,
})
}
请注意,在服务器上,您需要确保设置正确的 Content-Type:{ ContentType: "image/jpeg; charset=utf-8", 'x-amz-acl': 'public-read' }
因为它似乎 fetch 将字符集添加到 Content-Type。
您不需要使用 react-native-fs 或那个缓冲库。相反,只需使用 https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsArrayBuffer 读取文件,将结果传递给 fetch 的 body 参数。 readAsBinaryString 和 readAsDataUrl 给了我奇怪的结果。
注意:我不必将“;charset=utf-8”附加到我的 content-type header.
示例:
const fileReader = new FileReader();
fileReader.addEventListener('load', (event: any) => {
const buffer = event.target.result;
return fetch(link.url, {
method: 'PUT',
body: buffer,
})
.then((response) => {
if (!response.ok) {
throw new Error(
`${response.status}: ${response.statusText}`
);
}
return response;
})
.then(resolve, reject);
});
fileReader.addEventListener('error', reject);
fileReader.addEventListener('abort', reject);
fileReader.readAsArrayBuffer(file);
您也可以使用下一个解决方案:
/**
* @param {{contentType: string, uploadUrl: string}} resourceData for upload your image
* @param {string} file path to file in filesystem
* @returns {boolean} true if data uploaded
*/
async uploadImage(resourceData, file) {
return new Promise((resolver, rejecter) => {
const xhr = new XMLHttpRequest();
xhr.onload = () => {
if (xhr.status < 400) {
resolver(true)
} else {
const error = new Error(xhr.response);
rejecter(error)
}
};
xhr.onerror = (error) => {
rejecter(error)
};
xhr.open('PUT', resourceData.uploadUrl);
xhr.setRequestHeader('Content-Type', resourceData.contentType);
xhr.send({ uri: file });
})
}
然后从您的代码中调用此函数,例如:
let isSuccess = await uploadImage({
contentType: "image/jpeg",
uploadUrl: "http://my.super.web.amazon.service..."
}, "file:///path-to-file-in-filesystem.jpeg")
来源:https://github.com/react-native-community/react-native-image-picker/issues/61#issuecomment-297865475