React创建WordPress文章时特色图片上传失败问题排查
WordPress REST API 创建文章时特色图片关联失败问题解决
问题概述
使用React + Formik创建WordPress文章,提交表单后文章成功生成,但后台显示文章的特色图片字段值为0,图片未关联。控制台输出的featured_image为本地文件路径字符串(如C:\fakepath\react.png)。
错误原因
- WordPress API限制:无法直接通过
/posts端点上传图片并关联,必须先将图片上传到/media端点获取媒体ID,再将ID赋值给文章的featured_media字段。 - File字段处理错误:Formik默认的
Field组件处理type="file"时,返回的是文件路径字符串,而非实际的File对象,导致FormData无法正确传递文件。 - 字段名不匹配:WP API中文章的特色图片字段是
featured_media,而非代码中的featured_img,且该字段需要传入媒体ID,不是文件本身。
修复步骤
1. 修正File字段的获取方式
修改Formik的文件字段,通过setFieldValue手动设置真实的File对象:
import { useState, useRef } from "react"; import { Formik, Form, ErrorMessage, Field } from "formik"; import * as Yup from "yup"; import axios from "axios"; function CreatePost() { const [isLoaded, setIsLoaded] = useState(false); const [isPostCreated, setIsPostCreated] = useState(false); const fileInputRef = useRef(null); const initialValues = { title: "", content: "", featured_image: null, }; const validationSchema = Yup.object({ title: Yup.string().required(), content: Yup.string().required(), featured_image: Yup.mixed() .required("请选择图片") .test("fileType", "仅支持图片格式", (value) => { return value && ["image/jpeg", "image/png", "image/gif"].includes(value.type); }), }); // ... 后续代码
在表单中替换原来的File字段:
<div className="login__input"> <input type="file" name="featured_image" ref={fileInputRef} className="login__input__border" onChange={(e) => { props.setFieldValue("featured_image", e.target.files[0]); }} /> <div className="error"> <ErrorMessage name="featured_image" component="span" /> </div> </div>
2. 修改提交逻辑:先上传图片,再创建文章
调整onSubmit函数,先调用媒体上传接口获取ID,再用该ID创建文章:
async function onSubmit(data) { const authToken = localStorage.getItem("token"); try { // 1. 上传图片到media端点 const mediaFormData = new FormData(); mediaFormData.append("file", data.featured_image); const mediaResponse = await axios.post( `${import.meta.env.VITE_BASE_URL}/wp-json/wp/v2/media/`, mediaFormData, { headers: { "Content-Type": "multipart/form-data", Authorization: `Bearer ${authToken}`, }, } ); // 获取媒体ID const featuredMediaId = mediaResponse.data.id; // 2. 创建文章,传入featured_media字段 const postFormData = new FormData(); postFormData.append("title", data.title); postFormData.append("content", data.content); postFormData.append("featured_media", featuredMediaId); const postResponse = await axios.post( `${import.meta.env.VITE_BASE_URL}/wp-json/wp/v2/posts/`, postFormData, { headers: { "Content-Type": "multipart/form-data", Authorization: `Bearer ${authToken}`, }, } ); setIsPostCreated(!!postResponse.data.id); setIsLoaded(true); console.log(postResponse); } catch (error) { console.log(error.response?.data?.error || error.message); } }
关键说明
- WordPress的
/posts端点不支持直接上传图片,必须通过/media端点先上传获取ID。 - FormData传递文件时,必须传入真实的
File对象,而非路径字符串。 - 文章的特色图片字段名为
featured_media,值为媒体ID。
内容的提问来源于stack exchange,提问作者Timmy
相关产品推荐
相关产品推荐

