如何将Cloudinary原生JS上传代码适配至Remix框架?
在Remix中实现Cloudinary图片上传(适配原Vanilla JS示例)
1. 整合表单结构到Remix组件
先把原示例的HTML表单改造为Remix的Form组件,注意添加encType="multipart/form-data",同时加入Cloudinary上传所需的隐藏字段(需提前在Cloudinary后台配置未签名上传预设):
import { useState } from "react"; import { Form } from "@remix-run/react"; export default function PostForm() { const [previewUrl, setPreviewUrl] = useState(null); const [uploadStatus, setUploadStatus] = useState(""); // 处理文件选择与Cloudinary上传 const handleFileSelect = async (e) => { const file = e.target.files[0]; if (!file) return; // 生成本地预览图 const preview = URL.createObjectURL(file); setPreviewUrl(preview); // 组装Cloudinary上传表单数据 const formData = new FormData(); formData.append("file", file); formData.append("upload_preset", "你的上传预设名称"); try { setUploadStatus("上传中..."); const response = await fetch("https://api.cloudinary.com/v1_1/你的Cloudinary云名称/image/upload", { method: "POST", body: formData, }); const data = await response.json(); if (data.secure_url) { // 将Cloudinary返回的图片URL存入隐藏字段,提交表单时同步发送 document.getElementById("cloudinary-image-url").value = data.secure_url; setUploadStatus("上传成功"); } } catch (err) { setUploadStatus("上传失败,请重试"); console.error(err); } }; return ( <Form method="post" encType="multipart/form-data"> {/* 原有创建Post的字段 */} <input type="text" name="title" placeholder="Post标题" required /> {/* 图片选择控件 */} <input type="file" name="image" accept="image/*" onChange={handleFileSelect} /> {/* 存储Cloudinary返回的图片URL,用于表单提交 */} <input type="hidden" id="cloudinary-image-url" name="imageUrl" /> {/* 预览图与上传状态提示 */} {previewUrl && <img src={previewUrl} alt="图片预览" style={{width: "200px", marginTop: "10px"}} />} <p>{uploadStatus}</p> <button type="submit" disabled={uploadStatus === "上传中..."}>创建Post</button> </Form> ); }
2. Remix后端处理表单提交
在表单对应的路由文件中,编写action函数处理POST请求,获取Post数据与图片URL后完成创建逻辑:
import { ActionFunctionArgs, json } from "@remix-run/node"; export async function action({ request }: ActionFunctionArgs) { const formData = await request.formData(); const title = formData.get("title") as string; const imageUrl = formData.get("imageUrl") as string; // 替换为你的实际创建Post逻辑(比如存入数据库) // await createPost({ title, imageUrl }); return json({ success: true, post: { title, imageUrl } }); }
关键注意事项
- 务必在Cloudinary后台创建未签名上传预设,否则前端无法直接上传
- 替换代码中的
你的Cloudinary云名称和你的上传预设名称为实际配置值 - 若需要更高安全性,可将上传逻辑移至Remix后端(后端签名后调用Cloudinary API),前端仅负责传递文件到后端
内容的提问来源于stack exchange,提问作者Nuno Marques
相关产品推荐
相关产品推荐

