React Native 应用程序将照片上传到 Cloudinary 服务器并获取照片的链接。
来自 Image Picker 的文件通过两个步骤上传到 Cloudinary。第一步将照片上传到应用服务器:
import {DBStorageInteractor} from '../interfaces';
import {BASE_URL} from '../../../config/constants';
import ImageResizer from 'react-native-image-resizer';
import {ImagePickerResponse} from 'react-native-image-picker';
async uploadImage(photo: ImagePickerResponse, id: string): Promise<string> {
return new Promise<string>(async (resolve, reject) => {
if (!photo) {
reject(Error('Photo is not presented'));
return;
}
this.getBody(photo, id)
.then((body) => {
const headers = {
Accept: 'application/json',
'Content-Type': 'application/json',
};
const options = {
method: 'POST',
body: body,
headers: headers,
};
fetch(`${BASE_URL()}/api/images/upload`, options)
.then((response) => response.json())
.then((response) => {
const secureUrl = response.secure_url;
console.log('Uploaded successfully. Url=', secureUrl);
resolve(secureUrl);
})
.catch((error) => {
const message = `Failed uploading. Error=${error}`;
console.log(message);
reject(Error(message));
});
})
.catch((error) => {
reject(error);
});
});
}
getBody(photo: ImagePickerResponse, id: string): Promise<string> {
return new Promise((resolve, reject) => {
if (photo.fileSize < 100000) {
resolve(
JSON.stringify({
img: photo.data,
name: `eMia${id}.${this.getFileExtension(photo.uri)}`,
})
);
} else {
ImageResizer.createResizedImage(photo.uri, 400, 400, 'JPEG', 80)
.then(({uri}) => {
RNFS.readFile(uri, 'base64')
.then((data) => {
resolve(
JSON.stringify({
img: data,
name: `eMia${id}.${this.getFileExtension(photo.uri)}`,
})
);
})
.catch((error) => {
reject(error);
});
})
.catch((error) => {
reject(error);
});
}
});
}
getFileExtension(filename) {
return filename.slice((filename.lastIndexOf(".") - 1 >>> 0) + 2);
}
图片。 1. 客户端从Image Picker上传照片到服务器端,获取照片链接。
在第二步服务器端(在 NodeJS 上)处理两个步骤的请求。它将请求中的文件图像写入临时目录,然后将其上传到 Cloudinary 服务器:
const {Router} = require('express')
const router = Router()
const cloudinary = require('cloudinary').v2;
const fs = require('fs')
// /api/images/upload
router.post('/upload', async (req, res) => {
try {
const file = req.body.img;
const name = req.body.name;
const path = `tmp/${name}`;
// Write received fire in temporary folder
fs.writeFile(path, file, 'base64', (err) => {
if (err) {
console.log(err);
throw err
}
// Upload file to the Cloudinary server
cloudinary.uploader.upload(path)
.then((results) => {
res.status(200).json(results)
})
.catch((error) => {
res.status(400).json(error)
});
})
} catch (error) {
res.status(500).json(error)
}
}
)
图片。 2. 在NodeJS服务器上处理请求'/upload'。
在服务器端配置 Cloudinary:
const cloudinary = require('cloudinary').v2;
require('dotenv').config();
cloudinary.config({
cloud_name: process.env.cloud_name,
api_key: process.env.api_key,
api_secret: process.env.api_secret,
});
文件 .env(在项目的根目录中)包含以下参数:
cloud_name=<Cloudinary cloud name>
api_key=<API key from the Cloudinary project settings>
api_secret=<API secret from the Cloudinary project settings>