我尝试使用 Expo Image Picker 和 AWS SDK 将图像上传到我的 DigitalOcean Spaces,但我不断遇到此错误:
ERROR Error uploading image: [TypeError: Network request failed]
这是我用来上传图像的相关代码:
import AsyncStorage from '@react-native-async-storage/async-storage';
import axios from 'axios';
import * as ImagePicker from 'expo-image-picker';
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
import 'react-native-get-random-values'; // This polyfills crypto.getRandomValues
import { v4 as uuidv4 } from 'uuid';
import { spaces } from '../config/digitalOcean';
import 'react-native-url-polyfill/auto';
import { ReadableStream } from 'web-streams-polyfill';
globalThis.ReadableStream = ReadableStream;
export default function AddItems({ navigation }) {
const [produceName, setProduceName] = useState('');
const [quantity, setQuantity] = useState('');
const [price, setPrice] = useState('');
const [itemImage, setItemImage] = useState('');
const [phoneNumber, setPhoneNumber] = useState('');
const [uploading, setUploading] = useState(false);
const s3Client = new S3Client({
endpoint: spaces.url,
forcePathStyle: false,
region: "blr1",
credentials: {
accessKeyId: spaces.spacesKey,
secretAccessKey: spaces.spacesSecret
}
});
useEffect(() => {
const loadPhoneNumber = async () => {
try {
const storedPhoneNumber = await AsyncStorage.getItem('phone');
if (storedPhoneNumber) {
setPhoneNumber(storedPhoneNumber);
} else {
Alert.alert('Error', 'Phone number not found');
}
} catch (error) {
console.error('Error loading phone number from AsyncStorage:', error);
}
};
loadPhoneNumber();
}, []);
const pickImageAsync = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
allowsEditing: true,
quality: 1,
});
if (!result.canceled) {
uploadImage(result.assets[0]);
} else {
alert('You did not select any image.');
}
};
const getImageBlob = (uri) => {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = function() {
resolve(xhr.response);
};
xhr.onerror = function() {
reject(new Error('XMLHttpRequest failed'));
};
xhr.responseType = 'blob';
xhr.open('GET', uri, true);
xhr.send(null);
});
};
const uploadImage = async (imageAsset) => {
setUploading(true);
const fileName = `${uuidv4()}.jpg`;
try {
const response = await fetch(imageAsset.uri);
const blob = await getImageBlob(imageAsset.uri);
console.log("these happened without error");
console.log(response);
console.log(blob);
const params = {
Bucket: spaces.name,
Key: fileName,
Body: blob,
ACL: "public-read",
ContentType: 'multipart/form-data',
};
const data = await s3Client.send(new PutObjectCommand(params));
console.log(data);
const imageUrl = spaces.url + "/" + fileName;
setItemImage(imageUrl);
Alert.alert('Success', 'Image uploaded successfully');
} catch (error) {
console.error('Error uploading image:', error);
Alert.alert('Error', 'Failed to upload image');
}
setUploading(false);
};
const handleSubmit = async () => {
if (!produceName || !quantity || !price) {
Alert.alert('Error', 'All fields are required');
return;
}
try {
const formData = {
phoneNumber,
itemName: produceName,
quantity,
price,
itemImage,
};
const response = await axios.post(
'myurl/api/supplier/add-item',
formData
);
if (response.status === 200) {
Alert.alert('Success', 'Item added successfully!');
navigation.goBack();
}
} catch (error) {
console.error('Error adding item:', error.response?.data || error.message);
Alert.alert(
'Error',
error.response?.data?.message || 'Failed to add item, please try again'
);
}
};
我已尝试以下方法,但尚未找到解决方案:
尝试上传图像时出现网络请求失败错误的原因可能是什么?我处理图像 blob 或 AWS S3 配置的方式有问题吗?
尝试使用 fetch 创建像这样的 blob,并确保 DigitalOcean 空间上的 cors 策略已包含在 AllowedMethods 中放置和发布。
const getImageBlob = async (uri) => {
const response = await fetch(uri);
const blob = await response.blob();
return blob;
};