在Nuxt中复刻OpenAI API示例时遇500及JSON解析错误求助
问题排查:Nuxt复刻OpenAI官方示例时的500错误与
response.json()报错 问题背景
将OpenAI官方的React/Next示例复刻到Nuxt框架,创建了server/api/completion.js后端接口和index.vue前端页面,点击提交按钮时出现两个错误。
后端代码(server/api/completion.js)
import { Configuration, OpenAIApi } from 'openai' const configuration = new Configuration({ apiKey: import.meta.env.OPENAI_API_KEY }) const openai = new OpenAIApi(configuration) export default async function (req, res) { if (!configuration.apiKey) { res.status(500).json({ error: { message: 'OpenAI API key not configured, please follow instructions in README.md' } }) return } const animal = req.body.animal || '' if (animal.trim().length === 0) { res.status(400).json({ error: { message: 'Please enter a valid animal' } }) return } try { const completion = await openai.createCompletion({ model: 'text-davinci-003', prompt: generatePrompt(animal), temperature: 0.6 }) res.status(200).json({ result: completion.data.choices[0].text }) } catch (error) { if (error.response) { console.error(error.response.status, error.response.data) res.status(error.response.status).json(error.response.data) } else { console.error(`Error with OpenAI API request: ${error.message}`) res.status(500).json({ error: { message: 'An error occurred during your request.' } }) } } } function generatePrompt(animal) { const capitalizedAnimal = animal[0].toUpperCase() + animal.slice(1).toLowerCase() return `Suggest three names for an animal that is a superhero. Animal: Cat Names: Captain Sharpclaw, Agent Fluffball, The Incredible Feline Animal: Dog Names: Ruff the Protector, Wonder Canine, Sir Barks-a-Lot Animal: ${capitalizedAnimal} Names:` }
前端代码(index.vue)
<script setup> const animal = ref('') const result = ref('') const onSubmit = async () => { try { const response = await useFetch('/api/completion', { method: 'POST', body: JSON.stringify({ animal: animal.value }), headers: { 'Content-Type': 'application/json' } }) const data = await response.json() result.value = data.result } catch (error) { console.error(error) } } </script> <template> <div> <form @submit.prevent="onSubmit"> <label for="animal">Animal:</label> <input id="animal" v-model="animal" /> <button type="submit">Submit</button> </form> <p v-if="result">Result: {{ result }}</p> </div> </template>
出现的错误
- 网络错误:
POST http://localhost:3000/api/completion 500 (Internal Server Error) - 代码错误:
TypeError: response.json is not a function
问题排查与修复方案
1. 后端500错误修复
Nuxt 3的服务器路由采用H3框架规范,不兼容Next.js的req/res回调模式,需要调整接口写法:
修改后的server/api/completion.js:
import { Configuration, OpenAIApi } from 'openai' import { readBody, createError } from 'h3' import { useRuntimeConfig } from '#imports' export default defineEventHandler(async (event) => { // 用Nuxt官方方式获取环境变量 const config = useRuntimeConfig() const configuration = new Configuration({ apiKey: config.openaiApiKey }) const openai = new OpenAIApi(configuration) if (!configuration.apiKey) { return createError({ statusCode: 500, message: 'OpenAI API key未配置,请在.env中设置NUXT_OPENAI_API_KEY' }) } // 用H3的readBody获取POST请求体 const body = await readBody(event) const animal = body.animal || '' if (animal.trim().length === 0) { return createError({ statusCode: 400, message: '请输入有效的动物名称' }) } try { const completion = await openai.createCompletion({ model: 'text-davinci-003', prompt: generatePrompt(animal), temperature: 0.6 }) return { result: completion.data.choices[0].text } } catch (error) { if (error.response) { console.error(error.response.status, error.response.data) return createError({ statusCode: error.response.status, message: error.response.data.error?.message || 'OpenAI API请求失败' }) } else { console.error(`OpenAI API请求错误: ${error.message}`) return createError({ statusCode: 500, message: '请求过程中发生错误' }) } } }) function generatePrompt(animal) { const capitalizedAnimal = animal[0].toUpperCase() + animal.slice(1).toLowerCase() return `Suggest three names for an animal that is a superhero. Animal: Cat Names: Captain Sharpclaw, Agent Fluffball, The Incredible Feline Animal: Dog Names: Ruff the Protector, Wonder Canine, Sir Barks-a-Lot Animal: ${capitalizedAnimal} Names:` }
2. 前端response.json()错误修复
Nuxt的useFetch返回的是封装后的响应对象,不是原生Response,无需调用.json()方法:
修改后的index.vue:
<script setup> const animal = ref('') const result = ref('') const onSubmit = async () => { try { // useFetch返回包含data、error的响应对象,无需手动序列化body const { data, error } = await useFetch('/api/completion', { method: 'POST', body: { animal: animal.value }, headers: { 'Content-Type': 'application/json' } }) if (error.value) { console.error(error.value) return } result.value = data.value?.result } catch (err) { console.error(err) } } </script> <template> <div> <form @submit.prevent="onSubmit"> <label for="animal">Animal:</label> <input id="animal" v-model="animal" /> <button type="submit">Submit</button> </form> <p v-if="result">Result: {{ result }}</p> </div> </template>
3. 额外环境配置
在项目根目录创建.env文件,添加OpenAI密钥(Nuxt会自动识别带NUXT_前缀的变量):
NUXT_OPENAI_API_KEY=你的OpenAI_API_KEY
内容的提问来源于stack exchange,提问作者Ricardo de Paula
相关产品推荐
相关产品推荐

