React发起API POST请求报SyntaxError: Unexpected token < in JSON错误求助
错误根因
你遇到的报错本质是后端接口返回的内容不是JSON格式,而是HTML文本(<就是HTML的起始字符),前端强行调用res.json()解析就会触发这个错误。
问题排查&修改点
- 你已经用react-hook-form托管了表单值,不需要额外维护
solutestate、solventstate两个冗余状态,额外绑定的onChange、value属性可能导致表单值和托管状态不同步。 - 你当前用FormData格式提交请求,绝大多数Flask写的预测接口默认是接收
application/json格式的请求,你用FormData提交会触发参数校验错误,接口返回HTML格式的错误页,就会触发你遇到的报错。 - FormData的定义不要放在组件顶层,要放到
onSubmit函数内部,避免组件重渲染导致FormData被重置。
修复后代码(适配绝大多数接收JSON的接口)
const FirstProject = () => { const [fetchData, setFetchData] = useState(""); const [Error, setError] = useState(null); const { register, handleSubmit } = useForm({ defaultValues: { solute: "", solvent: "", }, }); const onSubmit = (data) => { fetch("https://flask-api-test1.herokuapp.com/predict", { method: "POST", headers: { "Content-Type": "application/json", }, // 直接传入react-hook-form收集的表单值,转成JSON字符串 body: JSON.stringify(data), }) // 先判断请求状态是否正常,再解析内容 .then((res) => { if (!res.ok) throw new Error(`请求错误,状态码:${res.status}`) return res.json() }) .then((result) => { setFetchData(result.result.predictions); }) .catch((err) => { setError(err.message); console.log(err); }); }; // 你原代码缺了return,这里补上 return ( <form onSubmit={handleSubmit(onSubmit)}> <input {...register("solute")} placeholder="溶质" /> <input {...register("solvent")} placeholder="溶剂" /> <input type="submit" /> </form> ) }
若接口确实要求提交FormData,用下面的调试方法定位问题
const onSubmit = (data) => { const formData = new FormData(); formData.set("solute", data.solute); formData.set("solvent", data.solvent); fetch("https://flask-api-test1.herokuapp.com/predict", { method: "post", body: formData, }) // 先把返回内容转成文本打印,确认是JSON再转格式 .then((res) => res.text()) .then((text) => { console.log('接口实际返回内容:', text) // 确认返回内容是JSON后再调用JSON.parse const result = JSON.parse(text) setFetchData(result.result.predictions); }) .catch((err) => { setError(err.message); console.log(err); }); };
内容的提问来源于stack exchange,提问作者harsh
相关产品推荐
相关产品推荐

