React Native blob/文件没有到达服务器



我被困在这里了。我不知道我做错了什么。我正试图从博览会图像选择器组件发送一个文件到服务器。表单发送了,但是图像没有发送。fetch命令立即给出"网络请求失败";错误。服务器确实收到请求,但是没有附加图像。

更多信息:

  • 我正在创建表单数据对象并将blob附加到它。我也试过用FormData.append("image", {uri, name: 'filename', type: 'image/filetype'}),大多数文章建议的方式,忽略TS错误,但它也失败了。

  • 我没有提交到AWS或Firebase,所以我没有使用这些库,我不知道他们在做什么不同于我在任何情况下。

  • 我没有为此设置任何特定的权限。我确实看到过一些关于上传权限的文章,但它们是5年前的,而且是在android 5.0之前。

下面是我用来提交的函数。pathToImage从ImagePicker返回。

const fetchImageFromUri = async (uri: string) => {
try {
const response = await fetch(uri);
const blob = await response.blob();
return blob;
} catch (error) {
console.log("fetchImageFromUri error:", error);
throw new Error("fetchImageFromUri");
}
};
const upload = async () => {
setMessage("");
setErrMessage("");
if (pathToImage != null) {
const fileToUpload = await fetchImageFromUri(pathToImage);
const formData = new FormData();
formData.append("action", "Image Upload");
formData.append("image", fileToUpload, "filename");
// from: https://stackoverflow.com/questions/71198201/react-native-unable-to-upload-file-to-server-network-request-failed
// most articles say this is the way to upload the file... Typescript gives an error
// because it only wants type 'string | Blob'
// let uriParts = pathToImage.split(".");
// let fileType = uriParts[uriParts.length - 1];
// formData.append("image", {
//   uri: pathToImage,
//   name: `photo.${fileType}`,
//   type: `image/${fileType}`,
// });
// create the header options
const options: RequestInit = {
method: "POST",
body: formData,
headers: {
"Content-Type": "multipart/form-data",
Accept: "image/jpeg, image/png",
},
};
try {
const res = await fetch(URL, options);

console.log("fetch returned"); // this line is never reached

if (!res.ok) {
throw new Error("Something went wrong");
}
const body = (await res.json()) as any;

if (body.code > 200) {
setErrMessage(body.msg);
} else {
setMessage(body.msg);
}
} catch (err: any) {
setErrMessage("There was an error in upload");
console.log("upload catch error:", err.message);
}
}
};

完整的代码可以在我的GitHub仓库中找到。

感谢Brandonjgs为我指明了正确的方向。我能解决这个问题。

这是新的上传功能。

const upload = async () => {
console.log("n***** Upload Image *****");
setMessage("");
setErrMessage("");
setLoading(true);
if (pathToImage) {
console.log("***** get other fields section *****");
const dataToSend: Record<string, string> = {};
dataToSend["action"] = "Image Upload";
console.log("***** Options section *****");
const options: FileSystemUploadOptions = {
headers: {
"Content-Type": "multipart/form-data",
Accept: "image/jpeg, image/png",
},
httpMethod: "POST",
uploadType: FileSystemUploadType.MULTIPART,
fieldName: "image",
parameters: dataToSend,
};
console.log("***** 'Fetch' section *****");
try {
const response = await FileSystem.uploadAsync(
URL,
pathToImage,
options
);
setLoading(false);
if (response.status >= 200 && response.status < 300) {
const body = JSON.parse(response.body);
setMessage(body.msg);
} else {
setErrMessage(`${response.status} Error: ${response.body}`);
}
} catch (err: any) {
console.error(err);
setErrMessage(err.message);
}
}
};

一定要查看文件系统。uploadAsync文档。它不返回标准的http响应,它自己格式化并返回:

  • status:错误码
  • header:从服务器返回的http头信息
  • body:服务器发送的任何内容;在我的例子中,它是JSON。请注意,如果服务器无响应或它是一个坏的URL,它返回一个HTML错误页面,而不是一个标准的错误消息字符串(我发现一个奇怪的选择,因为这是react native,我不一定导航到一个新的页面,当我做一个上传,我捕获字符串在一个状态对象发布响应)。

最新更新